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;};, Он делает то же самое, что и ваш "предложенный" синтаксис.

Другие вопросы по тегам