根据标准,constexpr offset_of的定义是否正确?

时间:2017-02-07 22:10:00

标签: c++ c++11 language-lawyer constexpr

我想知道根据c ++ 11标准,constexpr offset_of的定义是否正确。

根据this article,C ++ 98允许在数组声明中进行转换。我调整了文章中的代码以允许我的一些案例。我可以这样做吗?如果没有,有更好的方法吗?

template<typename T>
struct declval_helper { static T value; };

template<typename T, typename Z, typename U, Z U::*MPtr>
struct offset_helper {
    using TV = declval_helper<T>;

    static char for_sizeof[1 + (
        (char *)&(TV::value.*MPtr) -
        (char *)&TV::value
    )];
};

template<typename T, typename Z, typename U, Z U::*MPtr>
constexpr std::size_t offset_of() {
    return sizeof(detail::offset_helper<T, Z, U, MPtr>::for_sizeof) - 1;
}

用例:

struct Base { int data; };
struct Derived : Base { float data; };

constexpr std::size_t offset = offset_of<Derived, int, Base, &Base::data>();

1 个答案:

答案 0 :(得分:1)

不,它的结构不合理。

来自[dcl.array]:

  

如果常量表达式(5.20)存在,它应该是.right-side{ right:0; } 类型的转换常量表达式,其值应大于   零。

这里的常量表达式指的是数组绑定,这是可选的。转换的常量表达式来自[expr.const]:

  

类型为std::size_t转换常量表达式是一个表达式,隐式转换为类型T,其中转换后的表达式是一个常量表达式[...]

和一个常量表达式是:

  

条件表达式 T核心常量表达式,除非评估e,遵循规则   抽象机器(1.9)将评估以下表达式之一:[...] - e(5.2.10);

此声明:

reinterpret_cast

在数组的数组边界中使用隐式static char for_sizeof[1 + ( (char *)&(TV::value.*MPtr) - (char *)&TV::value )]; ,这使得它不是常量表达式,因此它的格式不正确。