以N3651为基础,
类范围内的变量模板是静态数据成员 模板
给出的例子是:
struct matrix_constants {
template <typename T>
using pauli = hermitian_matrix<T, 2>;
然而,以下所有定义都会出错:
struct foo
{
template <typename T>
T pi = T{3.14};
};
template <typename T>
struct foo2
{
template <typename U = T>
U pi = U{3.14};
};
template <typename T>
struct foo3
{
template <T>
T pi = 42;
};
error: member 'pi' declared as a template
是什么给出了?
答案 0 :(得分:4)
编辑:committee has spoken,Clang对于静态数据成员模板需要static
关键字是正确的。 14/1中给出的示例不正确。希望工作草案的下一次修订将消除文本中的含糊之处。
<小时/> 这个似乎是Clang中的一个错误,但标准草案中的措辞含糊不清。我认为意图是关键字
static
是隐含的。如果这不是意图,可能标准的措辞更像是“类范围的变量模板 必须 静态数据成员模板。”而不是“类范围的变量模板 是 静态数据成员模板。” (N3797§14/ 1)§14/ 1中给出的(公认的非规范性)示例声明了三个类成员变量模板,没有static
关键字:
struct matrix_constants {
template<class T>
using pauli = hermitian_matrix<T, 2>;
template<class T>
constexpr pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } };
template<class T>
constexpr pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } };
template<class T>
constexpr pauli<T> sigma3 = { { 1, 0 }, { -1, 0 } };
};
14.5.1.3类模板的静态数据成员[temp.static] / 1 ,特别是 使用static
中的示例:
struct limits {
template<class T>
static const T min; // declaration
};
template<class T>
const T limits::min = { }; // definition
所以至少不要禁止这样做。
作为@RichardSmith states in his comment,该部分的实际规范文本与该示例相矛盾。他们把Clang写成标准的文本,所以这个例子被诊断为格式错误。 The committee is aware that the wording for variable templates needs some help in various places,所以我确信在下一个草案/ C ++ 14中会有一些清理。
答案 1 :(得分:0)
如果你尝试第一个例子,clang立即咳出神奇的错误:
template <typename T, size_t N>
struct hermitian_matrix { };
struct foo
{
template <typename T>
using pauli = hermitian_matrix<T, 2>;
template <typename T>
constexpr pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } };
};
error: non-static data member cannot be constexpr; did you intend to make it static?
显然,在类范围内,变量模板需要声明为static。除非你宣布constexpr,否则clang不会咳出正确的错误,这可能会产生误导。除此之外,他们的静态数据成员示例:
struct foo
{
template <typename T>
static T bar;
};
template <typename T>
T foo::bar = T{3.14};
可能会让你失望,因为人们可能会认为变量成员模板的重点是替换静态数据成员。