Можно ли игнорировать функцию типа конечного возврата в c++11 в пользу функции вывода типа возвращаемого значения в c++14?
Когда я пропускаю возвращаемый тип выражения
Следующий код в C++11:
auto function(X x, Y y) -> decltype(x + y)
{
return x + y;
}
Равно следующему коду в C++14:
decltype(auto) function(X x, Y y)
{
return x + y;
}
Но дополнительно можно вывести возвращаемый тип без decltype
правил в C++14:
auto function()
{
return 0;
}
Когда я точно знаю, какой тип возврата
Следующий код в C++11:
auto function() -> int
{
return 0;
}
Равен следующему коду в C++03:
int function()
{
return 0;
}
Странный пример, который никогда не должен произойти
Следующий код в C++11:
auto function(X x, Y y) -> decltype(x * y)
{
return x; // Yeah! return x with the type of x * y expression!
}
Равно следующему коду в C++14:
decltype(auto) function(X x, Y y)
{
return static_cast<decltype(x * y)>(x);
}
Пожалуйста, поправьте меня, если приведенный выше код неверен и не работает должным образом.
Править, согласно комментарию (Yakk) : они на самом деле не равны, первый (C++11 пример) является неявным приведением, а второй (static_cast
изпримера C++14 ) является явным приведением.
Заключение
Как вы можете видеть, я могу сделать все, не используя функцию альтернативного синтаксиса функций C++11. Я не ошибаюсь? Могу ли я полностью забыть об этом без каких-либо технических проблем?
В общем случае можно избежать следующего синтаксиса:
auto function() -> TYPE
{
return 0;
}
В пользу следующего синтаксиса:
TYPE function() // TYPE can be: auto, decltype(auto), or ...
{
return 0;
}
Не забыл ли я какое-либо использование функции трейлинг-типа возврата C++11, что невозможно с функциейвозвращаемого типа вычитания функции C++14?
1 ответ:
Есть три важных различия между функцией, использующей автоматическое вычитание типа возврата, и функцией с явным типом возврата (даже если он вычисляется):
Вы не можете сделать SFINAE о вычисляемости возвращаемого типа, если вы не задаете его явно: вместо этого вы получаете жесткую ошибку. Почему? Поскольку SFINAE работает только с объявлением, а не с определением функций (SFINAE: (template-argument) substitution-failure не является ошибка).
Автоматический-возврат-тип-вычет , без SFINAE
SFINAE , но нет автоматического вывода типа возврата#include <iostream> int doit(int x, ...) { return x; } template<class X, class Y> auto doit(X x, Y y) #ifdef TRAILING_RETURN_TYPE -> decltype(doit(x) + doit(y)) #endif { return doit(x) + doit(y); } int main() { std::cout << doit(1, nullptr) << std::endl; }
В настоящий момент Вы не можете объявить функцию с ее фактическим типом возврата, если в определении используется автоматическое вычитание типа возврата, и она не может быть виртуальной. (Явное Правило)
7.1.6.4 автоматический спецификатор
[dcl.spec.auto]
13 повторные объявления или специализации функции или шаблона функции с объявленный тип возврата, использующий тип заполнителя, также должен использовать этот заполнитель, а не выводимый тип.
14 функция, объявленная с возвращаемым типом, использующим тип заполнителя, не должна быть виртуальной (10.3).Только функции с автоматическим вычитанием типа возврата могут возвращать лямбду, так как нет другого способа получить ее тип.
auto foo() { return [] {}; }
Ссылка на предложение, которое было включено в проект для C++1y:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3638.html