2014-12-13 3 views
5

Почему C++ 11 не имеют "шаблон" определений типов, какПочему у C++ 11 нет шаблона typedef?

template<typename T> typedef std::vector<T, myalloc<T>> vec; 

Вместо этого они только позволяют новый синтаксис:

template<typename T> using vec = std::vector<T, myalloc<T>>; 
+0

Возможно, просмотрите ссылки, перечисленные в конце [N2258] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2258.pdf)? –

+0

Алиасы шаблонов были необходимы, которые были введены в C++ 11, и было решено, что вместо 'typedef' следует использовать' use'. – 101010

+0

Поскольку синтаксис 'typedef' ужасен (он * расширяет синтаксис объявления переменных *!), Особенно для типов функций. 'использование' является более читаемым; если вам не нужна предварительная совместимость, просто замените все свои typedef на 'use' и наслаждайтесь тем, насколько чище код получает. – Griwes

ответ

8

n1406 было предложение Herb Sutter для "шаблонов TYPEDEF" который имитирует синтаксис в вашем вопросе. n1499, который предлагает «псевдонимы шаблонов», заменяет его, который содержит синтаксис using, который в настоящее время присутствует в C++ 11.

Один из основных недостатков «шаблонов typedef» рассматривается в обеих документах. От n1406:

В существующей практике, в том числе в стандартной библиотеке, имена типов вложенных внутри шаблонов хелперов класса используются для решения этой проблемы во многих случаях. Ниже приведен один пример этого обычного обходного решения ; основным недостатком является необходимость записи :: Тип при использовании имени typedef'd.

template< typename T > 
struct SharedPtr 
{ 
    typedef Loki::SmartPtr 
    < 
     T,    // note, T still varies 
     RefCounted,  // but everything else is fixed 
     NoChecking, 
     false, 
     PointsToOneObject, 
     SingleThreaded, 
     SimplePointer<T> // note, T can be used as here 
    > 
    Type; 
}; 

SharedPtr<int>::Type p; // sample usage, “::Type” is ugly 

Что мы действительно хотели бы быть в состоянии сделать это просто:

template< typename T > 
typedef Loki::SmartPtr 
    < 
    T,    // note, T still varies 
    RefCounted,  // but everything else is fixed 
    NoChecking, 
    false, 
    PointsToOneObject, 
    SingleThreaded, 
    SimplePointer<T> // note, T can be used as here 
    > 
    SharedPtr; 

SharedPtr<int> p;  // sample usage, “::Type” is ugly 

[...]

Обойти это некрасиво, и было бы хорошо, чтобы заменить он с первоклассной поддержкой языка, которая предлагает пользователям естественный шаблон C++ .

Эта «первоклассная языковая поддержка» поставляется в виде псевдонимов шаблонов. Теперь мы можем посмотреть на то, что n1499 должен сказать:

В этой статье мы сосредоточимся на описании механизма наложения спектров, что позволяет две семантики, упомянутые в N1406 сосуществовать, вместо того рассматривать как взаимоисключающие. Прежде всего, давайте рассмотрим пример игрушки:

template <typename T> 
class MyAlloc {/*...*/}; 

template <typename T, class A> 
class MyVector {/*...*/}; 

template <typename T> 
struct Vec { 
typedef MyVector<T, MyAlloc<T> > type; 
}; 

Vec<int>::type p; // sample usage 

Основная проблема с этой идиомой, и главным мотивирующим фактом для этого предложения является то, что идиома вызывает параметры шаблона для появляется в не выводимой контексте. То есть, невозможно будет вызывать функцию foo ниже, явно не указывая шаблон аргументов.

template <typename T> void foo (Vec<T>::type&); 

Кроме того, синтаксис несколько уродливый. Мы предпочли бы избежать вложенного вызова :: type. Мы предпочли бы что-то вроде следующего:

template <typename T> 
using Vec = MyVector<T, MyAlloc<T> >; //defined in section 2 below 

Vec<int> p;  // sample usage 

Обратите внимание, что мы специально избегаем термина «ЬурейеЕ шаблон» и ввести новый синтаксис с участием пары «с помощью» и «=», чтобы помочь избежать путаницы: мы не являются , определяющими любые типы здесь, мы , вводящий синоним (т.е.псевдоним) для абстракции тип-идентификатор (т. е. выражение типа), включающий параметры шаблона. Если шаблон параметров используются в выводимых контекстах в выражении типа затем всякий раз, когда псевдоним используются шаблон для формирования шаблона идентификатора, то значения соответствующих параметров шаблона можно сделать вывод - более на это последует. В любом случае теперь можно написать общие функции , которые работают в Vec<T> в выводимом контексте, а также улучшается синтаксис . Например, мы можем переписать foo как:

template <typename T> void foo (Vec<T>&); 

Мы подчеркиваем здесь, что одна из основных причин предложить шаблона псевдонимами был так, что вывод аргумента и призыв к foo(p) удастся.

Итак, вы можете видеть, что n1499 адресует проблемы в n1406, а также вводит синтаксис, который намного чище и легче читать.

+0

Зачем нужен 'template typedef MyVector > Vec;' также не решить проблему? – steveire

Смежные вопросы