tags:

views:

78

answers:

2

the following gives me ambiguous template instantiation with nvcc (combination of EDG front-end and g++). Is it really ambiguous, or is compiler wrong? I also post workaround à la boost::enable_if

template<typename T> struct disable_if_serial { typedef void type; };
template<> struct disable_if_serial<serial_tag> { };

template<int M, int N, typename T>
__device__
//static typename disable_if_serial<T>::type
void add_evaluate_polynomial1(double *R,
                         const double (&C)[M][N], double x,
                         const T &thread) {
    // ...
}

template<size_t M, size_t N>
__device__
static void add_evaluate_polynomial1(double *R,
                                     const double (&C)[M][N], double x,
                                     const serial_tag&) {
    for (size_t i = 0; i < M; ++i)
        add_evaluate_polynomial1(R, C, x, i);
}

// ambiguous template instantiation here.
add_evaluate_polynomial1(R, C, x, serial_tag());  
+5  A: 

AFAIK, the problem is that you have the nontype arguments inconsistently typed (that is, M and N are int here, but size_t there). This means not all template variable assignments from one can be used in the other, which means there is no partial ordering, hence the error message.

Unite the template nontype argument types and it should work.

jpalecek
thanks. This is not the first time I made this particular stupid mistake
aaa
+3  A: 

I have tested the code on Clang, GCC and Comeau. Comeau rejects it while GCC and Clang accept it. I think that for both groups of compilers there can be made points

  • Comeau follows the C++03 rule, which requires an "exact match (so the deduction does not rely on implicit conversions)" for the deduced template arguments. However this specification was horribly underspecified and has been completely rewritten for C++0x.

  • Clang and GCC seem to implement the rewritten rule, and this rule better specifies what "exact match" means. This specification goes fine with the different types of the array dimensions.

In any case, if you want to go fine with all compilers, then really go by the accepted answer and change the non-type parameter types to a common type :)

Johannes Schaub - litb
thank you.I went ahead and fix that, now both compilers and happy
aaa