mercredi 26 septembre 2018

Intel C++ compiler failing to select template function overload

The following code in C++11 compiles correctly with g++ 6.3.0 and result in the behavior that I consider correct (namely, the first function is picked). However with Intel's C++ compiler (icc 17.0.4) it fails to compile; the compiler indicates that multiple possible function overloads exist.

#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;
}

Here is the error reported by 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);
    ^

So my two questions are: which compiler is correct with respect to the standard? and how would you modify this code so that it compiles? (note that f is a user-facing API and I would like to avoid modifying its prototype).

Note that if I remove typename X = typename std::is_void<R>::type and the X x = X() argument in the second version of f, icc compiles it fine.

Aucun commentaire:

Enregistrer un commentaire