std :: declval()触发断言错误,并在GCC中发出警告

blu*_*rni 4 c++ gcc c++11

请考虑以下代码段:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这会在GCC的所有版本中触发警告静态断言失败,我在编译时尝试了它(4.7.3,4.8.1,4.9-some-git)-Wall -Wextra.例如,这是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,

如果要么使用return语句禁用警告供应bar,例如,

template <typename T>
decltype(foo<T>()) bar(T a)
{
    return a + a;
}
Run Code Online (Sandbox Code Playgroud)

断言失败消失了.在任何情况下,Clang ++ 3.3都不会触发断言错误.这是GCC的符合标准的行为吗?

Pot*_*ter 5

我在6月初制作的GCC 4.9副本只要我添加return {};throw;在函数内部就可以毫无怨言地编译它.没有return,它确实触发了静态断言.这肯定是一个错误,但只是一个小错误,因为该功能只在执行时"崩溃".

我在尝试以declval()常量表达式执行时看到了这个错误,所以在你的情况下可能会发生类似的事情."不能使用"可能是指使用ODR或使用结果.

也许在没有任何声明的情况下,它试图用它的内容制造一个decltype.甚至添加一个简单的语句,如0;静音错误.(但是static_assert( true, "" )甚至void(0)还不够.)

提起了一个GCC错误.