如何解决constexpr与const引用交互的奇怪行为
我用clang和gcc(主干版本)测试了以下代码。有人可以解释为什么纯X结构的案例不起作用,而按值捕获和使用const引用的包装案例都很好。
struct X {
constexpr X(const int &v) : x(v) {}
constexpr int Get() const { return x; }
private:
const int& x;
};
constexpr X f(const X& r) {
return r;
}
struct Y {
constexpr Y(const int &v) : x(v) {}
constexpr int Get() const { return x; }
private:
const int x;
};
constexpr Y f(const Y& r) {
return r;
}
struct Wrap {
constexpr Wrap(const int& v) : x(v) {}
constexpr Y Get() const { return Y{x}; }
private:
const int x;
};
int main() {
constexpr const int x = 10;
/* this does not work for some reason
constexpr X a(x);
static_assert(f(a).Get() == 10,"This should work.");
*/
// This works.
constexpr Y b(x);
static_assert(f(b).Get() == 10,"This should work.");
// This also works.
constexpr Wrap c(x);
static_assert(f(c.Get()).Get() == 10,"This should work.");
return 0;
}
解决方法
您在这里违反的规则:
constexpr X a(x);
是consetxpr
指针还是constexpr
引用必须引用具有静态存储持续时间的对象-这是其地址本身就是常量表达式的唯一方法。 x
的情况不是 。
但是一旦这样做(const
就是多余的):
static constexpr int x = 10;
然后其余的工作:
constexpr X a(x);
static_assert(f(a).Get() == 10,"This should work.");
具体规则为[expr.const]/11:
常量表达式是glvalue核心常量表达式,它引用的是常量表达式(如以下定义)的允许结果的实体,或者是其值满足以下条件的prvalue核心常量表达式:以下限制:
- 如果该值是类类型的对象,则每个引用类型的非静态数据成员都引用一个实体,该实体是常量表达式的允许结果,
[...]
一个实体是一个常量表达式的允许结果,如果它是一个具有静态存储持续时间的对象,该对象不是临时对象或者其值满足上述约束的临时对象,或者这是非立即函数。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。