C++11, с использованием typedef, templatized
Вместо
typedef struct
{
double x,y;
} Point;
C++11 поддерживает
using Point = struct {double x, y;};
К сожалению, этот подход не работает для типа T
template <typename T>
using Point = struct {T x, y;};
Есть ли способ решить проблему?
3 ответа
using Point = ...;
это псевдоним типа (формально называемый просто "псевдоним"). Т.е. это просто другой синтаксис для typedef
где участвующий тип назван в ...
,
template<typename T> using Point = ...;
является шаблоном псевдонима, где соответствующий тип снова назван в ...
,
Общим для шаблонов псевдонимов и псевдонимов является то, что оба должны ссылаться на идентификатор типа (C++11 [basic.scope.pdecl]p3). Идентификаторы типов должны в свою очередь называтьтипы. (Пойди разберись.)
Проблема в том, что template<typename T> struct {T x, y;}
это не тип, а шаблон класса, и как только что созданные шаблоны псевдонимов должны ссылаться на типы. Что касается изменения вашего кода для решения вашей проблемы, я понятия не имею, как вы не сказали, что это такое...;-] В связи с этим, пожалуйста, посмотрите, в чем проблема XY?
Есть ли причина, по которой вы хотите использовать псевдоним типа в этом случае? Чтобы избежать предвосхищения struct
Ключевое слово, это не так в C++.
Вы бы просто определили их напрямую: struct Point { double x, y; };
,
То же самое с делом шаблона:
template <typename T>
struct Point { T x, y; };
Я несколько не согласен с языковой адвокатурой в других ответах, поэтому решил написать свой.
Короче говоря, вы не можете использоватьtemplate <typename T> using Point = struct {T x, y;};
по той же причине, по которой вы не можете использовать template <typename T> struct {T x, y;};
,
Шаблон псевдонима все еще является шаблоном. И хотя в стандарте это не указано явно, это означает, что шаблон должен иметь имя (см. [Temp]/4 - Имя шаблона имеет связь...). Который вы не предоставляете.
Так что нет, вы не можете "решить проблему" без указания имени. Но вы также не можете просто бросить имя в объявлении псевдонима, например так: template <typename T> using Point = struct P {T x, y;};
, Стандарт явно запрещает это ([dcl.typedef]/2 - определение-типа-спецификатора-seq определения-типа-идентификатора не должно определять класс или перечисление).
Единственное, что вы можете сделать, будет выглядеть примерно так:
template <typename T>
struct Point {T x, y;};
template <typename T>
using PointAlias = Point<T>;
Что, как видите, бессмысленно (если, конечно, ваш Point
принимает несколько аргументов шаблона; в этом случае вы можете сделать отличный шаблон псевдонима).
Так что придерживайтесь простого template <typename T> struct Point {T x, y;};
, Он делает то же самое, что и ваш "предложенный" синтаксис.