Consider this snippet:
#include <utility>
template <typename U>
auto foo() -> decltype(std::declval<U>() + std::declval<U>());
template <typename T>
decltype(foo<T>()) bar(T)
{}
int main()
{
bar(1);
return 0;
}
This fires a warning and a static assertion failure in all versions of GCC I tried it on (4.7.3, 4.8.1, 4.9-some-git) when compiled with -Wall -Wextra
. For instance, this is the output of 4.8.1:
main.cpp: In instantiation of ‘decltype (foo<T>()) bar(T) [with T = int; decltype (foo<T>()) = int]’: main.cpp:12:7: required from here main.cpp:8:2: warning: no return statement in function returning non-void [-Wreturn-type] {} ^ In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/move.h:57:0, from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/stl_pair.h:59, from /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/utility:70, from main.cpp:1: /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/type_traits: In instantiation of ‘typename std::add_rvalue_reference< <template-parameter-1-1> >::type std::declval() [with _Tp = int; typename std::add_rvalue_reference< <template-parameter-1-1> >::type = int&&]’: main.cpp:8:2: required from ‘decltype (foo<T>()) bar(T) [with T = int; decltype (foo<T>()) = int]’ main.cpp:12:7: required from here /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/type_traits:1871:7: error: static assertion failed: declval() must not be used! static_assert(__declval_protector::__stop,
If one either disables the warnings or supplies bar
with a return statement, e.g.,
template <typename T>
decltype(foo<T>()) bar(T a)
{
return a + a;
}
the assertion failure disappears. Clang++ 3.3 does not fire assertion errors in any case. Is this standard-conforming behaviour from GCC?
bar
. – ascheplertypeid(*a_nullptr)
throws an exception, per standard. – Xeo