次のスニペットを検討してください。
#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;
}
これにより、GCC のすべてのバージョン (4.7.3、4.8.1、4.9-some-git) でコンパイルしたときに、警告と-Wall -Wextra
静的アサーション エラーが発生します。たとえば、これは 4.8.1 の出力です。
main.cpp: 'decltype (foo<T>()) bar(T) [with T = int; のインスタンス化中。decltype (foo<T>()) = int]': main.cpp:12:7: ここから必須 main.cpp:8:2: 警告: 非 void [-Wreturn-type] を返す関数に return ステートメントがありません {} ^ /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/move.h:57:0 からインクルードされたファイルで、 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/bits/stl_pair.h:59 から、 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/utility:70 から、 main.cpp:1 から: /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/type_traits: '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: 'decltype (foo<T>()) bar(T) [with T = int; から必要です。decltype (foo<T>()) = int]' main.cpp:12:7: ここから必須 /usr/lib/gcc/x86_64-pc-linux-gnu/4.8.1/include/g++-v4/type_traits:1871:7: エラー: 静的アサーションに失敗しました: declval() は使用しないでください! static_assert(__declval_protector::__stop,
警告を無効にするか、 returnbar
ステートメントを指定すると、たとえば、
template <typename T>
decltype(foo<T>()) bar(T a)
{
return a + a;
}
アサーションの失敗はなくなります。Clang++ 3.3 では、どのような場合でもアサーション エラーは発生しません。これは GCC の標準準拠の動作ですか?