xml*_*lmx 12 c++ static-assert language-lawyer constexpr c++11
#include <cstddef>
template<typename... Types>
constexpr std::size_t getArgCount(Types&&...) noexcept
{
return sizeof...(Types);
}
struct A
{
int n;
void f()
{
static_assert(getArgCount(n) > 0); // not ok, why?
}
};
int main()
{
int n;
static_assert(getArgCount(n) > 0); // ok
}
Run Code Online (Sandbox Code Playgroud)
为什么在编译时无法获得模板函数的参数计数?
错误信息:
1>test.cpp
1>test.cpp(17,45): error C2131: expression did not evaluate to a constant
1>test.cpp(17,42): message : failure was caused by a read of a variable outside its lifetime
1>test.cpp(17,42): message : see usage of 'this'
Run Code Online (Sandbox Code Playgroud)
rus*_*tyx 10
任何访问this外部constexpr上下文的内容都不是[expr.const] /2.1中定义的常量表达式:
表达式e是一个核心常量表达式 除非的评价Ë,以下抽象机的规则,将评估下列表达式之一:
this,但作为e的一部分的constexpr函数或constexpr构造函数除外;
(我们需要this访问n才能getArgCount通过引用传递给它)
这就是为什么第一种情况不编译的原因。
第二种情况之所以编译,是因为它不涉及非常数的lvalue到rvalue的转换(sizeof(n)实际上并不“读取” n)。
为了说明这一点,还将编译以下内容:
struct A
{
int n;
void f()
{
int m = n;
static_assert(getArgCount(m) > 0); // ok, m doesn't need `this`
}
};
Run Code Online (Sandbox Code Playgroud)
注意:如果引用的生存期在该上下文中开始,则其本身在constexpr上下文(该Types&&部分)中不会破坏“ constexpr-ness”:[expr.const] /2.11.2。
另一个例子:
struct A
{
int n;
void f()
{
static_assert(sizeof(n) > 0); // ok, don't need this for sizeof(A::n)
}
};
Run Code Online (Sandbox Code Playgroud)
以下内容无法编译:
int n = 1;
static_assert(getArgCount(n+1) > 0); // not ok, (n+1) "reads" n
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |