【问题标题】:Intel C++ compiler failing to select template function overload英特尔 C++ 编译器无法选择模板函数重载
【发布时间】: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&lt;R&gt;::typeX x = X() 参数,icc 可以正常编译。

【问题讨论】:

  • typename std::is_void&lt;R&gt;::type总是bool。你确定你不是打算在enable_if 中使用它吗?
  • 不,std::is_void&lt;R&gt;::type 的类型为 std::integral_constant&lt;bool, value&gt;std::is_void&lt;R&gt;::value_typeboolstd::is_void&lt;R&gt;::valuetruefalse
  • 抱歉,您是对的。但是我关于在enable_if_t 中使用is_void::value 的问题是存在的。
  • 在完整代码中,我将x 传递给另一个具有两个重载的函数,一个采用std::integral_constant&lt;bool, true&gt; 参数,另一个采用std::integral_constant&lt;bool, false&gt; 参数。我知道这很令人困惑,因为我删除了这两个函数的内容,似乎我没有声明类型名 X,我只是想将测试用例剥离到最小的重现错误。

标签: c++11 templates g++ overloading icc


【解决方案1】:

这是 Intel Compiler 17.0 Update 4 中的一个错误。GCC 的行为在这种情况下是正确的。此问题已在 Intel Compiler 18.0 Update 4 及更高版本中得到解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多