С помощью 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 особенно делает использование static
:
struct limits {
template<class T>
static const T min; // declaration
};
template<class T>
const T limits::min = { }; // definition
так что, по крайней мере, это не запрещено.
Как @RichardSmith утверждает в своем комментарии, Настоящий нормативный Текст раздела противоречит примеру. Они пишут Clang к тексту стандарта, поэтому пример диагностируется как плохо сформированный. Комитет осознает, что формулировка переменных шаблонов нуждается в некоторой помощи в разных местах., так что я уверен, что в следующем проекте / C ++ 14 будет некоторая очистка.
Если вы попробуете первый пример, 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?
Очевидно в области видимости, переменные шаблоны должны быть объявлены как статические. clang не исправляет правильную ошибку, если вы не объявите ее как constexpr, что может ввести в заблуждение. А также, их пример статического члена данных:
struct foo
{
template <typename T>
static T bar;
};
template <typename T>
T foo::bar = T{3.14};
может сбить вас с толку, потому что можно подумать, что весь смысл шаблонов переменных элементов заключается в замене статических элементов данных.