Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > SFINAE


Автор: UnrealMan 1.12.2006, 11:17
Есть ли в стандарте информация насчёт SFINAE или же это просто особенность отдельно взятых компиляторов? Интересует, собственно, перечень конструкций, неудачное образование которых не приводит к ошибкам. Например, конструкция

Код
ClassTemplateName<sizeof T(1, 1)>

может не быть корректно построенным типом из-за того, что у T нет подходящего конструктора, однако принцип SFINAE тут не работает (по крайней мере, у меня компилятор (MinGW-3.4.4) ругается, если не существует подходящего конструктора).

Автор: JackYF 1.12.2006, 16:18
Цитата(UnrealMan @  1.12.2006,  11:17 Найти цитируемый пост)
ClassTemplateName<sizeof T(1, 1)>

А что, у нас в зависимости от выполненного конструктора меняется размер типа?  smile 
sizeof(T) сложно написать???

Зачем так извращаться?  smile 

Автор: UnrealMan 1.12.2006, 18:58
Цитата(JackYF @  1.12.2006,  16:18 Найти цитируемый пост)
Зачем так извращаться?  

Если бы здесь работал принцип SFINAE, то можно было бы узнать, есть подходящий контруктор у класса или нет, причём вместо ошибки компиляции (когда подходящего конструктора нет) избирать другой способ поведения программы. Да и вообще, если бы любую подобную ошибку использования типа можно было б обернуть в sizeof и на это дело распространялся принцип SFINAE, этому принципу цены б тогда не было  smile

Напомню, что принцип SFINAE (substitution failure is not an error) заключается в том, что если при инстанцировании шаблона функции составление какого-либо типа её сигнатуры терпит неудачу, то такая функция исключается из списка кандидатов по части наилучшего соотвествия среди перегруженных функций, вместо того чтобы вызывать ошибку компиляции (увы, более точного определения дать не могу, поэтому и спрашиваю о наличии подробного описания в стандарте). Например, здесь

Код
void Func(...);
template <class T>
    typename T::Type Func(const T &);
void f() { Func(1); } // выбирается void Func(...) 

у типа T может не быть типа-члена Type. В таком случае вторая функция будет исключена из перечня рассматриваемых при выборе наилучшего соотвествия в перегрузке.

Автор: Daevaorn 1.12.2006, 19:23
http://en.wikipedia.org/wiki/SFINAE

Автор: UnrealMan 1.12.2006, 19:31
Это я уже читал – там представлена довольно скудная информация. Хоть там и есть ссылка на стандарт, но стандарт-то старый (1998 года), у меня же в наличии только 2003 года. Никаких интересующих меня подробностей в этом пункте 14.8.3 я у себя не нашёл...

Автор: JackYF 1.12.2006, 19:50
Цитата(Daevaorn @  1.12.2006,  19:23 Найти цитируемый пост)
http://en.wikipedia.org/wiki/SFINAE 


Это было мне? Так я уже это просмотрел...



Все... я понял. Не разобрался сначала.

Автор: UnrealMan 1.12.2006, 20:23
О! Кажется, я нашёл то, что искал: похоже, все случаи изложены в 14.8.2 smile

Цитата
Type deduction may fail for the following reasons:

— Attempting to create an array with an element type that is void, a function type, or a reference type, or attempting to create an array with a size that is zero or negative. [Example:

Код
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array

]
— Attempting to use a type that is not a class type in a qualified name. [Example:

Код
template <class T> int f(typename T::B*);
int i = f<int>(0);

]
— Attempting to use a type in the qualifier portion of a qualified name that names a type when that type does not contain the specified member, or if the specified member is not a type where a type is required. [Example:

Код
template <class T> int f(typename T::B*);
struct A {};
struct C { int B; };
int i = f<A>(0);
int j = f<C>(0);

]
— Attempting to create a pointer to reference type.
— Attempting to create a reference to a reference type or a reference to void.
— Attempting to create "pointer to member of T" when T is not a class type. [Example:

Код
template <class T> int f(int T::*);
int i = f<int>(0);

]
— Attempting to perform an invalid conversion in either a template argument expression, or an expression used in the function declaration. [Example:

Код
template <class T, T*> int f(int);
int i2 = f<int,1>(0); // can’t conv 1 to int*

]
— Attempting to create a function type in which a parameter has a type of void.
— Attempting to create a cv-qualified function type.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)