【发布时间】:2018-11-03 20:08:35
【问题描述】:
考虑以下代码sn-p:
template <bool> struct B { };
template <typename T>
constexpr bool pred(T t) { return true; }
template <typename T>
auto f(T t) -> decltype(B<pred(t)>{})
{
}
clang++ (trunk) 编译代码
-
g++ (trunk) 编译失败并出现以下错误:
src:7:34: error: template argument 1 is invalid auto f(T t) -> decltype(B<pred(t)>{}) ^ src:7:34: error: template argument 1 is invalid src:7:34: error: template argument 1 is invalid src:7:34: error: template argument 1 is invalid src:7:34: error: template argument 1 is invalid src:7:34: error: template argument 1 is invalid src:7:25: error: invalid template-id auto f(T t) -> decltype(B<pred(t)>{}) ^ src:7:36: error: class template argument deduction failed: auto f(T t) -> decltype(B<pred(t)>{}) ^ src:7:36: error: no matching function for call to 'B()' src:1:24: note: candidate: 'template<bool <anonymous> > B()-> B<<anonymous> >' template <bool> struct B { }; ^ src:1:24: note: template argument deduction/substitution failed: src:7:36: note: couldn't deduce template parameter '<anonymous>' auto f(T t) -> decltype(B<pred(t)>{}) ^
尽管 g++ 的诊断具有误导性,但我认为这里的问题是t 不是常量表达式。将代码更改为...
decltype(B<pred(T{})>{})
...修复 g++ 上的编译错误:live example on godbolt.org
什么编译器在这里表现正确?
【问题讨论】:
-
为什么你的
f函数里没有return语句? -
@YSC 不要吹毛求疵 :)
-
如果你真的实例化
fclang也会抱怨。 -
@Rakete1111 我也没有,但
f(std::integral_constant<int, 0>{})被clang接受... -
我认为您的问题与以下内容非常相关:“
auto f(std::integral_constant<int, 0> t) -> std::integral_constant<int, t>;有效吗?”(即,在某些情况下,您可以将函数参数用作常量表达式)。 .clang 接受它,gcc 不接受。如果这是有效的,这意味着您的模板对某些T有效,因此clang 不抛出错误是正确的,否则,gcc 是正确的。
标签: c++ c++11 language-lawyer constexpr constant-expression