【问题标题】:Sizeof member variable of a template type-argument模板类型参数的 sizeof 成员变量
【发布时间】:2014-07-02 09:19:52
【问题描述】:

我想为一个结构类型确定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?

【问题讨论】:

  • sizeof 下的表达式不求值,所以你可以放心使用items[0].val
  • @n.m 有趣,我不知道。知道为什么这个特定的 sizeof 表达式会失败吗?

标签: c++ templates sizeof


【解决方案1】:

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() 实际上不会被调用。

【讨论】:

  • “一般的解决方法是取消引用空指针(在非评估上下文中有效)”——真的吗?
  • @Yakk 好吧,每个人都假设它在 C++03 中;参考文献open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 进行一些讨论。当然,在 C++11 中,我们有 std::declval
  • @Yakk C 中的offsetof 宏通常在a similar way 中实现。
  • @james 标准标题可以为所欲为;从某种意义上说,它们是编译器的一部分。如果用户代码不被丢弃,则用户代码不能依赖 UB。标准头可以。如果编译器改变了它对 UB 的响应,它必须改变标头。对于用户代码来说,永远审计每个编译器更改是不切实际的。
猜你喜欢
  • 2021-07-25
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多