Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ ambiguous template instantiation

Tags:

c++

templates

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());  
like image 514
Anycorn Avatar asked Dec 17 '25 18:12

Anycorn


2 Answers

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.

like image 193
jpalecek Avatar answered Dec 20 '25 06:12

jpalecek


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 :)

like image 39
Johannes Schaub - litb Avatar answered Dec 20 '25 06:12

Johannes Schaub - litb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!