Sizeof模板类型参数的成员变量

时间:2014-07-02 09:19:52

标签: c++ templates sizeof

我想确定sizeof结构类型的特定成员变量,我将其作为模板参数传递给函数。但是,我从编译器得到一个错误,说sizeof操作数是非法的(我在Windows 7中使用VS2010)。

考虑以下计划:

#include <vector>
#include <fstream>

struct MyFloat {
    float val;
    MyFloat(){val=rand()/(RAND_MAX+1.f);};
};
struct MyDouble {
    double val;
    MyDouble(){val=rand()/(RAND_MAX+1.);};
};

template<class T>
void serializeArrayToFile(const std::string &filename, const std::vector<T> &items) {
    const size_t nbytes = sizeof(T::val); // <--- Error C2070
    std::ofstream os(filename.c_str(),std::ios::out+std::ios::binary);
    for(size_t i=0; i<items.size(); ++i)
        os.write((char*)(&items[i].val),nbytes);
    os.close();
};

void main() {
    const int N = 15;
    std::vector<MyFloat> arr_float(N); // Filled randomly by default constructor
    std::vector<MyDouble> arr_double(N); // Filled randomly by default constructor
    serializeArrayToFile<MyFloat>("myfloat_array.dat",arr_float);
    serializeArrayToFile<MyDouble>("mydouble_array.dat",arr_double);
}

这会产生以下错误:     错误C2070:'':非法操作数大小。

有人可以解释为什么sizeof(T::val)是非法的以及我应该如何确定sizeof T :: val,考虑到输入向量可能为空?

1 个答案:

答案 0 :(得分:5)

sizeof应用于不带对象命名的非静态数据成员是C ++ 11特性;它被引入paper n2253中的语言。符合标准的C ++ 03编译器不允许这种用法;如果可能的话,你应该看看你是否可以使用符合标准的C ++ 11编译器。

[请注意,与该论文相反,sizeof(S::m + 42)实际上是在最终的C ++ 11标准中允许的;我不知道什么时候改变了。]

一般的解决方法是取消引用空指针(在非计算上下文中有效):

sizeof(((T*) 0)->val)

但是,您有一个类型为T的对象,因此可以写:

sizeof(items.front().val)

即使向量为空,这也是有效的,因为sizeof是非评估的上下文,因此实际上不会调用front()