【发布时间】:2018-09-26 16:04:07
【问题描述】:
C++11 中的以下代码可以使用 g++ 6.3.0 正确编译,并导致我认为正确的行为(即选择第一个函数)。但是,使用 Intel 的 C++ 编译器(icc 17.0.4)无法编译;编译器指出存在多个可能的函数重载。
#include <iostream>
template<typename R, typename ... Args>
static void f(R(func)(const int&, Args...)) {
std::cout << "In first version of f" << std::endl;
}
template<typename R, typename ... Args, typename X = typename std::is_void<R>::type>
static void f(R(func)(Args...), X x = X()) {
std::cout << "In second version of f" << std::endl;
}
double h(const int& x, double y) {
return 0;
}
int main(int argc, char** argv) {
f(h);
return 0;
}
下面是icc报的错误:
test.cpp(18): error: more than one instance of overloaded function "f" matches the argument list:
function template "void f(R (*)(const int &, Args...))"
function template "void f(R (*)(Args...), X)"
argument types are: (double (const int &, double))
f(h);
^
所以我的两个问题是:哪个编译器在标准方面是正确的?您将如何修改此代码以使其编译? (注意f 是一个面向用户的 API,我想避免修改它的原型)。
请注意,如果我在f 的第二个版本中删除typename X = typename std::is_void<R>::type 和X x = X() 参数,icc 可以正常编译。
【问题讨论】:
-
typename std::is_void<R>::type总是bool。你确定你不是打算在enable_if中使用它吗? -
不,
std::is_void<R>::type的类型为std::integral_constant<bool, value>。std::is_void<R>::value_type是bool,std::is_void<R>::value是true或false。 -
抱歉,您是对的。但是我关于在
enable_if_t中使用is_void::value的问题是存在的。 -
在完整代码中,我将
x传递给另一个具有两个重载的函数,一个采用std::integral_constant<bool, true>参数,另一个采用std::integral_constant<bool, false>参数。我知道这很令人困惑,因为我删除了这两个函数的内容,似乎我没有声明类型名 X,我只是想将测试用例剥离到最小的重现错误。
标签: c++11 templates g++ overloading icc