2012-05-10 1 views
4

У меня есть макросы, которые работают с типами и начальными значениями. Мне нужно, чтобы бросить начальное значение vIni к vType (vIni всегда конвертируются в vType, иногда он имеет тот же тип). vIni также может быть пустым, и в этом случае vType должен быть неинициализирован или инициализирован по умолчанию. Результат передается в шаблонную функцию.Какие временные элементы не могут быть инициализированы с помощью `someType()` в C++ 11?

Короче говоря,

template<typename T> void foo(const T& o); 

foo(vType(vIni)); 
foo(vType()); 

должны компилировать.

Я уже обнаружил, что foo(unsigned int()) или foo(int*()) не компилируется, но его можно обойти с помощью typedef.

Что такое другие случаи (помимо встроенных типов с пробелами и указателями), которые потерпят неудачу?

+0

Очевидно, что 'недействительными()', но есть больше, чтобы сделать с тем, что вы не можете иметь 'void' объектов, чем точный синтаксис. – MSalters

+0

Возможный дубликат http://stackoverflow.com/questions/4669131/how-to-check-if-a-template-argument-is-default-constructible, также см. Http: //en.cppreference.com/w/cpp/types/is_default_constructible –

+0

@ChristopherCreutzig: это не тот вопрос, о котором я могу сказать. Речь идет не только о самом типе, но и о том, как назван тип (следовательно, «можно работать с typedef»). Разумеется, ответ на этот предполагаемый обман не отвечает на этот вопрос. –

ответ

5

Короткое (слегка упрощенное) ответ: «он будет работать не для чего-либо другого, кроме простого типа».

5.2.3/1 говорит:

простого типа-специфический эр (7.1.6.2) или Ьурепате-специфический эр (14,6), а затем в скобках выражения-списке конструкции значение заданного типа с учетом списка выражений.

простого типа спецификатор может быть либо именем одно слова для типа (необязательно плюс некоторые :: материала для области, и/или аргументы шаблона, которые сами по себе не должна быть простыми спецификаторами типа) или a decltype выражение. Возможности перечислены в 7.1.6.2.

unsigned int и int* не являются простыми спецификациями. Любой спецификатор составного типа будет терпеть неудачу, поэтому cv-qualification, типы массивов, типы функций, типы указателей, включая указатель-к-функции и указатель-к-члену, будут нуждаться в typedef.

Также исключены идентификаторы типа многословного типа, такие как unsigned char, long double. Для вашего первого примера, unsigned будет работать вместо unsigned int.

Ьурепат-спецификатор тип предшествует typename, используемый в шаблонах утверждать, что зависимое имя действительно тип, а не член данных или функцию-члена.

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

+0

Удивительно, но типовые составные типы работают: 'std :: vector ()'. В соответствии с 7.1.6.2, _imple-template-id_ является спецификатором _simple-type_ – MSalters

+1

Люди часто создают псевдоним или идентификатор для таких целей, то есть 'alias :: type()' – Puppy

+0

@DeadMG : yep, это лучше, чем моя вещь с участием 'declspec'. –

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