I have this code (simplified from a more complex version):
template <class... A1> class Test {
public:
template <class... A2> void print (void(*function)(A2...,A1...)) {
}
};
void test_print (int a, float b, double c) {
}
int main () {
Test<float,double> test;
test.print<int> (&test_print);
}
If I compile it on GCC 4.6.3 using g++ -std=c++0x filename.cpp
it compiles fine however on clang 3.0 using clang++ -std=c++0x filename.cpp
it throws the following error:
filename.cpp:14:10: error: no matching member function for call to 'print'
test.print<int> (&test_print);
~~~~~^~~~~~~~~~
filename.cpp:3:33: note: candidate template ignored: failed template argument deduction
template <class... A2> void print (void(*function)(A2...,A1...)) {
^
1 error generated.
On GCC 4.7.2 there is also an error:
filename.cpp: In function 'int main()':
filename.cpp:14:33: error: no matching function for call to 'Test<float, double>::print(void (*)(int, float, double))'
filename.cpp:14:33: note: candidate is:
filename.cpp:3:33: note: template<class ... A2> void Test::print(void (*)(A2 ..., A1 ...)) [with A2 = {A2 ...}; A1 = {float, double}]
filename.cpp:3:33: note: template argument deduction/substitution failed:
filename.cpp:14:33: note: mismatched types 'float' and 'int'
Now the question is: why is it failing or what am I doing wrong?
As part of resolving http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1399, it was decided that a parameter pack that is non-deducible will not participate in deduction, hence keeping the explicitly specified arguments within the parameter list, but not disturbing the matching of subsequent arguments to subsequent function parameters. However those added rules do not necessarily apply for deduction when comparing types (which is a sub-algorithm of the deduction of the set of parameters against the arguments for a function call).
I would argue that the resolution should apply to your situation aswell and regard it as simply an area where the specification is not entirely clear. You may want to send a bug report to the respective compilers and they may want to send an issue report to WG21 for asking to clarify this (although I am not sure I would go as far as saying that this is a normative spec issue - the Standard says elsewhere that non-deducible contexts do not participate in deductions).
Note as A1
is a parameter of the enclosing class template (and hence become normal parameters when the class is instantiated), you can omit them and keep the same meaning as far as template argment deduction is concerned
class Test {
public:
template <class... A2> void print (A2..., float, double) {
}
};
int main () {
Test test;
test.print<int> (1, 1.0f, 1.0); // works
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With