我试图在SO中找到类似的回答问题,但没有成功。 问题是为什么在编译时使用已知的模板参数的编译时值在编译时类型已知的编译时被认为是错误?常识告诉我,这段代码可以。在这种情况下怎么了? 谢谢!
#include <array>
using Cont = std::array<int, 2>;
class A
{
Cont a_ = {};
public:
int& at(bool first)
{
static_assert(sizeof(a_) / sizeof(int) == 2); // OK
static_assert(a_.size() > 1); // error: non-constant condition for static assertion. error: use of 'this' in a constant expression
return a_[first ? 0 : 1];
}
};
更新:它看起来像是重复的,但可能不是因为在link下的问题中,该演讲是关于运行时评估的,但是这里看起来a_.size()可以是在编译时进行评估。
UPDATE2 更清晰的示例(在考虑了答案和评论之后)
#include <array>
using Cont = std::array<int, 2>;
// OK
void checkSize(const Cont& b)
{
static_assert(b.size() == 2);
}
class A
{
Cont a_ = {};
public:
constexpr void checkSize() const
{
Cont b = {};
static_assert(b.size() == 2); // OK
static_assert(sizeof(a_) / sizeof(int) == 2); // OK
static_assert(a_.size() == 2); // error: non-constant condition for static assertion. error: use of 'this' in a constant expression
}
};
表明 this 中的问题与评估 a_.size()有关。但是为什么在那里需要它,尽管 a _ 被编译器称为非虚拟类型,并且 size()可以在编译时求值,但这可能是另一个问题,因此我将检查第一个答案。
答案 0 :(得分:6)
std::array::size
即使是constexpr
函数也不是static
函数。这意味着它需要调用一个对象实例。
在这种情况下,at
不是constexpr
†,因此this
也不是_a
。由于_a
不是constexpr
,因此_a.size()
的结果也不是constexpr
。
†即使是,身体仍然isn't considered constexpr
。
答案 1 :(得分:3)
a_
是类A
的成员。
a_.size()
是this->a_.size()
的简化形式,因为size不是静态函数,这意味着要访问a_
,必须访问this
。
this
是指向类A的指针,不是使static_assert
失败的编译时间常数。
使用模板可能更容易:
template<int N>
class B {
std::array<int, N> a_;
public:
int& at(bool first)
{
static_assert((sizeof(a_) / sizeof(int)) == 2, "Sizeof operator"); // OK
static_assert(N > 1, "Size method"); // No problem here
return a_[first ? 0 : 1];
}
};