Search code examples
c++templatesc++11gccnvcc

C++ variadic template: different priorities in gcc and nvcc/intel


Having a problem with the next code:

#include <iostream>
#include <functional>
using namespace std;

template<typename... Args>
inline double foo(function<double (Args...)> fun, Args... args) {
    return fun(args...);
}

template<typename... Args, typename... ArgsTmp>
double foo(function<double (Args...)> fun, ArgsTmp... args) {
    return foo(fun, 1., args...);
}

int main() {

    function<double (double, double, double)> fun = [&](double x, double y, double z) -> double {
        return x+y+z;
    };

    cout << foo(fun) << endl;
}

When I compile it with gcc everything goes fine. But if I'm trying to compile it, for example, with intel or nvcc-7.5(which is actually my goal) I'm getting the following error:

more than one instance of overloaded function "foo" matches the argument list:
            function template "double foo(std::vector<limits, std::allocator<limits>>, std::function<double (Args...)>, Args...)"
            function template "double foo(std::vector<limits, std::allocator<limits>>, std::function<double (Args...)>, ArgsTmp...)"
            argument types are: (std::vector<limits, std::allocator<limits>>, std::function<double (double, double, double)>, double, double, double)
...
1 error 

Is there any way to let the compiler know explicitly that when Args==ArgsTmp (in the second template) the following inplementation of foo() should be rejected?


Solution

  • You may try SFINAE and enable_if

    template<typename... Args, typename... ArgsTmp>
    std::enable_if_t<!std::is_same<std::tuple<Args...>,
                                   std::tuple<ArgsTmp...>>::value,
                     double>
    foo(function<double (Args...)> fun, ArgsTmp... args) {
        return foo(fun, 1., args...);
    }