std::array<...>::size()
是非static
constexpr
方法;作为constexpr
,我可以将其用作模板参数:
#include <array>
#include <stdio>
int main(void) {
std::array<char, 12> a = {{ "Hello world" }};
std::cout << "size() = " << a.size() << ", data() = \"" << a.data() << "\"" << std::endl;
std::array<char, a.size()> b = a;
std::cout << "size() = " << b.size() << ", data() = \"" << b.data() << "\"" << std::endl;
}
但是,如果std::array<...>
是模板参数,则情况将变得不确定:
template <typename T>
void copy(T const& a) {
std::array<char, a.size()> c = a;
std::cout << "size() = " << c.size() << ", data() = \"" << c.data() << "\"" << std::endl;
}
GCC高兴地编译了此[1],而CLANG拒绝了[2],
<source>:6:20: error: non-type template argument is not a constant expression
std::array<char, a.size()> c = a;
[1] https://godbolt.org/z/Ru7Y3F
[2] https://godbolt.org/z/LYJcpo
根据标准,哪个是正确的?
P.S。
是的,我知道我可以使用std::tuple_size
解决它:
template <typename T>
void copy(T const& a) {
std::array<char, std::tuple_size<T>::value> c = a;
std::cout << "size() = " << c.size() << ", data() = \"" << c.data() << "\"" << std::endl;
}
答案 0 :(得分:3)
C语是正确的。
您正在评估的引用类型的id表达式(a
)没有预先的初始化,这在常量表达式中是不允许的。
表达式
e
是核心常量表达式,除非根据抽象机的规则对e
的求值将对以下表达式之一求值:>
...
一个 id-expression ,它引用引用类型的变量或数据成员,除非该引用具有先前的初始化,并且其中一个都具有
- 初始化
使用常量表达式或
其生存期始于
e
的评估;...