Code: Select all
#include <iostream>
template<typename return_type, typename... argument_types>
return_type invoke(return_type (*func)(argument_types...), argument_types&&... args)
{
return func(std::forward<argument_types>(args)...);
}
int add(const int i, const int j) { return i + j; }
int main() {
std::cout << invoke<int, const int, const int>(&add, 4, 5) << std::endl;
}
Code: Select all
$ g++ -std=c++11 -o test test.cpp
test.cpp: In function ‘int main()’:
test.cpp:12:59: error: no matching function for call to ‘invoke(int (*)(int, int), int, int)’
std::cout << invoke<int, const int, const int>(&add, 4, 5) << std::endl;
^
test.cpp:12:59: note: candidate is:
test.cpp:4:13: note: template<class return_type, class ... argument_types> return_type invoke(return_type (*)(argument_types ...), argument_types&& ...)
return_type invoke(return_type (*func)(argument_types...), argument_types&&... args)
^
test.cpp:4:13: note: template argument deduction/substitution failed:
test.cpp:12:59: note: mismatched types ‘const int’ and ‘int’
std::cout << invoke<int, const int, const int>(&add, 4, 5) << std::endl;
^
After template argument substitution, the first argument of invoke is int(*)(const int, const int), which matches the signature of add exactly (and is equivalent to int(*)(int, int)).
It seems to me like g++ (correctly) drops the const qualifiers from the arguments of add, but fails to drop them from the arguments of the function pointer expected by invoke before matching the signatures of the expected function pointer and the passed-in function pointer.
So the question is in the title. Is this a bug I should report against g++ or am I thinking wrong here?