Я думал, что эти две функции должны иметь одинаковый тип возвращаемого значения:
template<class T>
decltype(auto) f(T&& a){return a;}
decltype(auto) g(auto&& a){return a;}
Тем не менее, используя gcc7, эти функции проверяют:
int i;
static_assert(std::is_same< decltype(f(i)), int& >::value);
static_assert(std::is_same< decltype(g(i)), int >::value);
Почему типы возврата g и f различны?
Определение
decltype(auto) g(auto&& a){return a;}
не является стандартным C ++. Это может быть частью новой функции Concepts Lite. g ++ предоставляет синтаксис как расширение (даже без -fconcepts
).
Компилирование с -Wpedantic
на самом деле выдает предупреждение:
warning: ISO C++ forbids use of 'auto' in parameter declaration [-Wpedantic]
decltype(auto) g(auto&& a){return a;}
^~~~
Поскольку поведение еще не стандартизировано, неясно, static_assert
должен быть правдивым или нет — интуитивно я согласен, что decltype(g(i))
должно быть int&
хоть. Это может быть просто «дефектом» в реализации g ++ не-членская функция auto
параметры.
Самая близкая стандартная вещь к тому, что вы пытаетесь сделать, это лямбда-выражение:
auto z = [](auto&& a) -> decltype(auto) { return a; };
В случае z
, static_assert
работает как положено:
static_assert(std::is_same< decltype(z(i)), int& >::value);
Других решений пока нет …