这是一个错误还是故意的(使用VS2017更新15.3.4)?
以下内容无法编译,因为CustomType
是非文字。
class A
{
public:
// ... some constructors
inline constexpr auto Value() const { return _value; }
private:
const CustomType _value;
}
但这完全没问题:
template< //... some templates
>
class A
{
public:
// ... some constructors
inline constexpr auto Value() const { return _value; }
private:
const CustomType _value;
}
为什么!?如果没有使用constexpr,我是否会在第一时间错过任何好处?我在第二个实例中使用constexpr获得了什么好处,或者编译器只是懒惰而完全忽略了错误?或者这一切都是故意这样做的,因为我不知道泛型类和非泛型类之间存在某些差异。
目前,我只能假设这是故意的,因为它使用模板参数提供元编程功能,这在我目前的情况下根本不需要。那么为什么不能首先在constexpr中返回非文字类型呢?我知道这个帖子中有很多问题,但也许只有一个答案就足够了。
为清楚起见,请运行以下命令:
class CustomType
{
public:
inline CustomType(const int& val)
: _value(val) {}
inline constexpr auto Value() const { return _value; }
private:
int _value;
};
template<int N>
class A
{
public:
inline constexpr A(const CustomType& Val)
: _value(Val) {}
inline ~A() {}
inline constexpr A(const A& rhs)
: _value(rhs._value) {}
inline constexpr const A& operator=(const A& rhs) const { return rhs; }
inline constexpr auto Value() const { return _value; }
private:
const CustomType _value;
};
如果删除template<int N>
,代码将不再编译。
答案 0 :(得分:4)
从最新的标准草案[dcl.constexpr]/6(我的重点):
如果constexpr函数模板的实例化模板特化或类模板的成员函数无法满足constexpr函数或constexpr构造函数的要求,那么该特化仍然是constexpr函数或constexpr构造函数,即使调用这样的函数不能出现在常量表达式中。 如果在被视为非模板函数或构造函数时模板的特化不满足constexpr函数或constexpr构造函数的要求,则模板格式错误,无需诊断。
您的函数显然无法满足constexpr函数的要求,因为它的返回类型不是文字类型。这与上面引用的条款相结合,会让您相信您的代码实际上是格式错误的,无需诊断(这几乎就是发生的事情)。不过,我希望constexpr使用成员函数来导致诊断。
另请参阅the accepted answer问题 Why do templates allow constexpr function members with non-constexpr constructors? ,该问题处理完全相同的情况,但函数恰好是自由函数而不是成员函数。< / p>
答案 1 :(得分:0)
模板类中的方法在实际使用之前并未实际实例化。也许编译器会检查它的语法健全性,但绝不会检查语义。