#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
}
为什么在编译时无法获得模板函数的参数计数?
错误消息:
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'
答案 0 :(得分:10)
在this
上下文之外访问constexpr
的任何内容都是不是常量表达式,如[expr.const]/2.1所定义:
表达式e是核心常量表达式 除非对 e 的求值,按照抽象机的规则,将求出其中一个以下表达式:
this
,但在constexpr
函数或constexpr
构造函数中被评估为 e 的一部分;
(我们需要this
才能访问n
,以便通过引用将其传递给getArgCount
)
这就是为什么第一种情况不编译的原因。
第二种情况之所以编译,是因为它不涉及非常数的lvalue-to-rvalue conversion(sizeof(n)
实际上没有“读取” n
)。
为证明这一点,还将编译以下内容:
struct A
{
int n;
void f()
{
int m = n;
static_assert(getArgCount(m) > 0); // ok, m doesn't need `this`
}
};
注意:如果引用的生命周期始于{{3},则在constexpr
上下文(Types&&
部分)内本身不会破坏“ constexpr-ness”。 }}。
另一个例子:
struct A
{
int n;
void f()
{
static_assert(sizeof(n) > 0); // ok, don't need this for sizeof(A::n)
}
};
以下内容无法编译:
int n = 1;
static_assert(getArgCount(n+1) > 0); // not ok, (n+1) "reads" n