constexpr 静态成员什么时候不再是 constexpr?
When does a constexpr static member stop being a constexpr?
我有这个片段。
#include <iostream>
#include <string>
struct JustStr {
JustStr(const std::string& x) : val(x) {}
static constexpr bool pred = false;
std::string val;
};
template <typename T>
class C {
private:
T x;
public:
C(T x_) : x(x_) {}
void f() {
if constexpr (!x.pred) {
std::cout << x.val << std::endl;
}
}
};
template<typename T>
void f2(T x) {
T y(x);
if constexpr (!y.pred) {
std::cout << x.val << std::endl;
}
}
int main() {
C<JustStr> c(JustStr("yes"));
c.f(); // Fails
f2(JustStr("yes")); // Succeeds
return 0;
}
我的问题是:c.f();
和 f2(JustStr("yes"));
不应该同时失败或成功吗?为什么一个失败,为什么另一个成功?
有一个 list of things 阻止表达式被视为核心常量表达式。
你不能做的一件事是评估:
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part of e
;
在 f()
中,我们正在评估 this
以查看 x.pred
是什么(因为它确实是 this->x.pred
),但 f()
不是' 一个 constexpr 函数。所以这个要点排除了 c.f()
。如果 f()
是 constexpr
,那么这将编译。
在 f2()
中,我们不会在任何地方评估 this
,因此该项目符号不适用。我们进行左值到右值的转换,但它确实引用了 complete non-volatile const object with a preceding initialization, initialized with a constant expression。没有其他适用。所以没关系。
我有这个片段。
#include <iostream>
#include <string>
struct JustStr {
JustStr(const std::string& x) : val(x) {}
static constexpr bool pred = false;
std::string val;
};
template <typename T>
class C {
private:
T x;
public:
C(T x_) : x(x_) {}
void f() {
if constexpr (!x.pred) {
std::cout << x.val << std::endl;
}
}
};
template<typename T>
void f2(T x) {
T y(x);
if constexpr (!y.pred) {
std::cout << x.val << std::endl;
}
}
int main() {
C<JustStr> c(JustStr("yes"));
c.f(); // Fails
f2(JustStr("yes")); // Succeeds
return 0;
}
我的问题是:c.f();
和 f2(JustStr("yes"));
不应该同时失败或成功吗?为什么一个失败,为什么另一个成功?
有一个 list of things 阻止表达式被视为核心常量表达式。
你不能做的一件事是评估:
this
, except in a constexpr function or a constexpr constructor that is being evaluated as part ofe
;
在 f()
中,我们正在评估 this
以查看 x.pred
是什么(因为它确实是 this->x.pred
),但 f()
不是' 一个 constexpr 函数。所以这个要点排除了 c.f()
。如果 f()
是 constexpr
,那么这将编译。
在 f2()
中,我们不会在任何地方评估 this
,因此该项目符号不适用。我们进行左值到右值的转换,但它确实引用了 complete non-volatile const object with a preceding initialization, initialized with a constant expression。没有其他适用。所以没关系。