类范围的可变模板

Variable template at class scope

本文关键字:范围      更新时间:2023-10-16

使用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

什么给出?

编辑:委员会已经说了,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 die die 使用 static

struct limits {
  template<class T>
    static const T min; // declaration
};
template<class T>
  const T limits::min = { }; // definition

至少不禁止这样做。

正如@richardsmith在他的评论中指出的那样,本节的实际规范文本与示例相矛盾。他们将叮当声写成标准的文本,因此该示例被诊断为不构型。委员会意识到,可变模板的措辞需要在各个地方提供一些帮助,因此我确信下一个草稿/C 14。

如果尝试第一个示例,则立即咳嗽魔术错误:

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?

显然在类范围内,需要将可变模板声明为静态。除非您将其宣布为误导,否则Clang不会咳嗽正确的错误。除此之外,他们的静态数据成员的示例:

struct foo
{
    template <typename T>
    static T bar;
};
template <typename T>
T foo::bar = T{3.14};

可能会把您丢掉,因为人们可能会认为可变成员模板的整个点是替换静态数据成员。