【发布时间】:2018-01-06 01:44:16
【问题描述】:
另一个“在 g++ 和 clang++ 之间谁是对的?” C++ 标准大师的问题。
下面的程序
#include <iostream>
void foo (int v)
{ std::cout << "foo(), int version (" << v << ')' << std::endl; }
void foo (double v)
{ std::cout << "foo(), double version (" << v << ')' << std::endl; }
template <typename T, typename R>
void bar (T v, R(*fn)(T))
{ fn(v); }
int main ()
{ bar(1, foo); }
使用 g++(6.3.0,也可以使用 Wandbox 的 8.0.0)编译和运行,但是使用 clang++(3.9.1,但也可以使用 Wandbox 的 6.0.0)编译它我得到以下错误
tmp_002-11,14,gcc,clang.cpp:29:4: error: no matching function for call to 'bar'
{ bar(1, foo); }
^~~
tmp_002-11,14,gcc,clang.cpp:25:6: note: candidate template ignored: couldn't
infer template argument 'R'
void bar (T v, R(*fn)(T))
^
1 error generated.
像往常一样,问题是:谁是对的? g++ 还是 clang++?
【问题讨论】:
-
返回类型不是函数签名的一部分。仍然似乎违反直觉。我会使用 std:: 函数,所以这里也可以使用 lambda 和仿函数。
-
foo在T被修复之前是模棱两可的。固定T后,R应该可以推演,但我认为推演是一次性完成的。 -
@kamikaze 已经可以传递非捕获 lambda。话虽如此,使用模板参数会更好。
-
void bar (R(*fn)(T), T v)都无法编译的事实让我觉得 clang 是对的。 -
clang 是对的。重载决议出现在模板推导之后。 gcc 太热心了。
标签: c++ templates g++ type-inference clang++