g ++和clang ++不同的行为推断函数的模板返回类型

时间:2017-07-30 12:17:30

标签: c++ templates g++ type-inference clang++

另一个"谁在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 ++?

1 个答案:

答案 0 :(得分:0)

Clang是正确的,但是由于一个微妙的原因:在模板推导过程中允许过载集,但是deduction on that one argument必须能够选择其中一个来推断。 (如果为零匹配,则总体扣除失败;如果多于一个,则扣除忽略该参数。)此处,foo匹配R(*fn)(T),因此无法从该参数推断出R (即使他们都同意),因此根本没有。