输入流函数模板决议问题导致程序不简洁

输入流函数模板决议问题导致程序不简洁

这两天写代码,遇到这么一个模板决议的问题:
    有一个类 A,其中有两个数据成员(方便起见都是 public )。为了从其它部分(比如文件)读入数据,我为 A 类重载了输入流操作符。代码如下所示:
程序1

typedef  struct  tagA  {
    UINT32  biSize;
    UINT32  biCount;
}
 A;

template 
< typename DataStream >
DataStream
&   operator >> (DataStream &  a_data, A &  a_fileHeader)
{        
    a_data
>>a_fileHeader.biSize>>a_fileHeader.biCount;

    
return a_data;        
}


    一般使用标准IO流的话,这样做至少在编译上是没有问题的(读二进制文件不行,后有补充)。
    在我的程序中,我目前只是测试时用文件读取,到后期,肯定会换成其它形式(可能是直接大块类似的数据整在一起,放在内存中之类),所以我打算为数据源写一个包装类,在目前的阶段,直接转到标准IO文件读取,后期再修改数据源类。因为使用数据源类需要保持与标准IO的写法一致( cin>>xx ),所以这个类要为每种基本类型重载输入流操作符。这些重载的代码结构都是一样的,只是数据类型不同,因此用模板是最好的,所以一开始,我写成了下面这个样子:
程序2

class  DataFromFile
{
public:
    DataFromFile(CHAR 
const *a_fileName)
        :dataStream(a_fileName, std::ios::binary
|std::ios::in)
    
{ assert(dataStream.good());}
    
~DataFromFile() 
    
{ dataStream.close();}
public:
    template 
<typename T>
    inline DataFromFile
& operator>> (T& a_data)        
    
{                                                  
        dataStream.read((CHAR 
*)&a_data, sizeof(T));   
        
return *this;                                     
    }

private:
    std::fstream dataStream;
}
;


    但在实际使用时,像下面的语句,就发生了编译问题:

DataFromFile source( " 11.bin " );
A dest;
source
>> dest; 


    编译器对这段代码抱怨,说无法确定使用哪个模板……
    当然,我是希望编译器在这里使用程序一中的非成员模板函数,然后在那个模板函数中,再用程序2中的成员模板函数来实例化基本类型的输入操作。可是编译器没有这么智能,我理解,这里用A做模板参数的话,确实有二义性。
    想来想去没想到好的办法消除这种二义性,只好修改代码,去掉其中一个的模板定义。类比地思考一下,标准IO并没有发生这个问题,因为标准IO的输入流操作并不是模板函数,而这里的DataFromFile类,明显使用模板会比较优雅,但二义性的问题不知道怎么解决。最后没办法,改成用宏来实现,代码如下:
程序3

#define  InputForBuildIn(Type)                         \
inline DataFromFile
&   operator >>  (Type &  a_data)        \
{                                                     \
    dataStream.read((CHAR 
*)&a_data, sizeof(Type));   \
    
return *this;                                     \
}


class  DataFromFile
{
public:
    DataFromFile(CHAR 
const *a_fileName)
        :dataStream(a_fileName, std::ios::binary
|std::ios::in)
    
{ assert(dataStream.good());}
    
~DataFromFile() 
    
{ dataStream.close();}
public:
    InputForBuildIn(INT8)
    InputForBuildIn(UINT8)
    InputForBuildIn(INT16)
    InputForBuildIn(UINT16)
    InputForBuildIn(INT32)
    InputForBuildIn(UINT32)
private:
    std::fstream dataStream;
}
;


    问题是没有了,但总觉得不是滋味。(不知道有没有更好的解决办法?哪位大侠指点下?)


PS:
    对 C++ 的标准 IO 流还不熟,在以二进制方式打开文件时,使用 >> 操作符无法读入数据?一开始的时候调了很久,后来才发现这里可能有问题,转成使用 .read() 方法来读数据,就成功了。标准 IO 还是得好好再补补啊。

你可能感兴趣的:(输入流函数模板决议问题导致程序不简洁)