Когда я пытаюсь скомпилировать этот код, я получаю следующую ошибку компилятора в Visual Studio 2012:
error C2440: 'default argument' : cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'
Мой код:
namespace bar {
template<typename T> void foo();
template<> void foo<int>() {}
}
struct A {
void(*f)();
template<typename T> inline void set_func(void(*f)()=bar::foo<T>) {this->f=f;}
};
int main(void) {
A a;
a.set_func<int>();
return 0;
}
Когда я двигаюсь bar::foo
в глобальное пространство имен, я больше не получаю ошибку. Кто-нибудь может объяснить, пожалуйста?
Я отредактировал приведенный выше код, чтобы устранить путаницу в функциях-членах и специализации шаблонов. Я также удалил typedef, который дает еще более странную версию той же ошибки: cannot convert 'void(_cdecl*)(void)' to 'void(_cdecl*)(void)'
Поскольку это, очевидно, ошибка в самом компиляторе, все, что я могу сделать, это создать обходной путь для достижения того же эффекта.
Я удалил аргументы по умолчанию и использовал перегруженный метод следующим образом:
template<typename T> inline void set_func() {this->f=bar::foo<T>;}
template<typename T> inline void set_func(void(*f)()) {this->f=f;}
Еще одно решение этой проблемы.
typedef void (*FunctionPointer)(int, int);
class Template
{
public:
template<typename Type>
static void Function(int Arg0, int Arg1)
{
// Code and Stuff
}
// ORIGINAL FUNCTION - Produces compile errors.
// Produces - error C2440: 'default argument' : cannot convert from 'overloaded-function' to 'FunctionPointer' (VS2012 SP5 x64)
template<typename Type>
void Original(FunctionPointer Arg = &Template::Function<Type>)
{
// Code and Stuff
}
// WORKAROUND FUNCTION - Compiles fine.
// Default Arg parameter to NULL and initialize default parameter inside function on runtime.
template<typename Type>
void Original(FunctionPointer Arg = NULL)
{
if (Arg == NULL)
Arg = &Template::Function<Type>;
// Code and Stuff
}
}