为什么我无法在编译时获取模板函数的参数计数?
Why can't I get the argument count of a template function at compile-time?
#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'
在 constexpr
上下文之外访问 this
的任何内容都 不是 常量表达式,如 [expr.const]/2.1:
中所定义
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
this
, except in a constexpr
function or a constexpr
constructor that is being evaluated as part of 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`
}
};
注意:如果引用的生命周期在该上下文中开始,则在 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)
}
};
以下将无法编译:
int n = 1;
static_assert(getArgCount(n+1) > 0); // not ok, (n+1) "reads" n
#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'
在 constexpr
上下文之外访问 this
的任何内容都 不是 常量表达式,如 [expr.const]/2.1:
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
this
, except in aconstexpr
function or aconstexpr
constructor that is being evaluated as part of 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`
}
};
注意:如果引用的生命周期在该上下文中开始,则在 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)
}
};
以下将无法编译:
int n = 1;
static_assert(getArgCount(n+1) > 0); // not ok, (n+1) "reads" n