Автоматический вывод типа возвращаемого значения
От: Шахтер Интернет  
Дата: 25.04.15 19:08
Оценка: 100 (4)
С этой фичей есть одна тонкость.
Поясню на примере.

Казалось бы, в чем разница между двумя следующими декларациями?


template <class T>
auto Add(T a,T b) { return a+b; }

template <class T>
auto Add(T a,T b) -> dectype( a+b ) { return a+b; }


А вот в чем. Когда вы навешиваете явный тип через decltype, то вы фактически добавляете неявный концепт к определению функции. Т.е. если вывод типа при подстановке аргументов шаблона провалится, то функция будет молча отброшена. А в первом примере -- нет. Иногда это важно (если есть семейство перегруженных шаблонов).
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: Автоматический вывод типа возвращаемого значения
От: Кодт Россия  
Дата: 25.04.15 22:47
Оценка: 4 (1)
Здравствуйте, Шахтер, Вы писали:

Ш>А вот в чем. Когда вы навешиваете явный тип через decltype, то вы фактически добавляете неявный концепт к определению функции. Т.е. если вывод типа при подстановке аргументов шаблона провалится, то функция будет молча отброшена. А в первом примере -- нет. Иногда это важно (если есть семейство перегруженных шаблонов).


Если очень надо сделать так, чтобы и decltype был, и SFINAE не вмешивалось, то можно прибегнуть к такой загогулине: сломать SFINAE
class failure {}; // нечто, непригодное к использованию

// типы для foo

struct nonplusable {};
struct nonplusable2 {};

// вывод типа для первой перегрузки: всегда успешный, но иногда болезненный

template<class T> auto foo_1_hint(T x) -> decltype(x+x);
failure foo_1_hint(...); // если эту ветку убрать, то SFINAE опять включится

// перегрузки foo

template<class T> auto foo(T x) -> decltype(foo_1_hint(x)) { cout << "foo1"; return x+x; }
void foo(nonplusable2) { cout << "foo2"; }
void foo(...) { cout << "foo3"; }

int main()
{
  foo(1); // foo1
  foo(nonplusable()); // foo1 failure вместо случайного попадания в foo3
  foo(nonplusable2()); // foo2
}
Перекуём баги на фичи!
Re[2]: Автоматический вывод типа возвращаемого значения
От: Шахтер Интернет  
Дата: 26.04.15 08:05
Оценка: +1
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Шахтер, Вы писали:


Ш>>А вот в чем. Когда вы навешиваете явный тип через decltype, то вы фактически добавляете неявный концепт к определению функции. Т.е. если вывод типа при подстановке аргументов шаблона провалится, то функция будет молча отброшена. А в первом примере -- нет. Иногда это важно (если есть семейство перегруженных шаблонов).


К>Если очень надо сделать так, чтобы и decltype был, и SFINAE не вмешивалось, то можно прибегнуть к такой загогулине: сломать SFINAE


Это какой-то экзотический случай. Как раз SFINAE штука полезная. Смысл моего поста (наверно, я не очень ясно выразил эту мысль) -- не спешите оптимизировать код и отбрасывать decltype.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.