У меня есть такой код, который компилирует штрафы во всем компиляторе, который я тестировал, кроме VS2010. Я стараюсь не использовать здесь специфические функции C++ 11, поэтому он может компилироваться на устаревшем компиляторе, таком как gcc 4.1.VS2010 SFINAE и ошибка перегрузки функции
#include <iostream>
using namespace std;
// Simplified variant class
struct Var
{
template <class T>
Var(T t) {}
Var(void) {}
};
// Simplified argument array class
struct FuncArgs
{
};
/** Make a wrapper around the given function */
template <int line, typename Ret, Ret Func()>
Var WrapFuncT(const FuncArgs & args)
{
Var ret;
ret = Func(); return ret;
}
/** Make a wrapper around the given function */
template <int line, void Func()>
Var WrapFuncT(const FuncArgs & args)
{
Var ret;
Func(); return ret;
}
// Unary
template <int line, typename Ret, typename Arg1, Ret Func(Arg1)>
Var WrapFuncT(const FuncArgs & args)
{
Var ret; Arg1 arg;
ret = Func(arg);
return ret;
}
template <int line, typename Arg1, void Func(Arg1)>
Var WrapFuncT(const FuncArgs & args)
{
Var ret; Arg1 arg;
Func(arg);
return ret;
}
// Binary
template <int line, typename Ret, typename Arg1, typename Arg2, Ret Func(Arg1, Arg2)>
Var WrapFuncT(const FuncArgs & args)
{
Var ret; Arg1 arg1; Arg2 arg2;
ret = Func(arg1, arg2);
return ret;
}
template <int line, typename Arg1, typename Arg2, void Func(Arg1, Arg2)>
Var WrapFuncT(const FuncArgs & args)
{
Var ret; Arg1 arg1; Arg2 arg2;
Func(arg1, arg2);
return ret;
}
#define WrapFunc(X, Y, ...) &WrapFuncT<__LINE__, X, Y, ## __VA_ARGS__ >
int testFunc()
{
return 42;
}
void testFunc2(int value)
{
cout<<value<<endl;
}
typedef Var (*NamedFunc)(const FuncArgs &);
int main()
{
NamedFunc a, b;
a = WrapFunc(int, testFunc);
b = WrapFunc(int, testFunc2);
}
Visual Studio 2010 компилятор давится это с ошибкой:
In line 'a = WrapFunc(int, testFunc);' : error C2440: 'specialization' : cannot convert from 'int (__cdecl *)(void)' to 'void (__cdecl *const)(int)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
error C2973: 'Type::WrapFuncT' : invalid template argument 'int (__cdecl *)(void)'
In line 'template <int line, typename Arg1, void Func(Arg1)>' : see declaration of 'Type::WrapFuncT'
Похоже VS2010 не находит прежнее определение template < int line, typename Ret, Ret Func(void) >
с Ret = int
для int testFunc(void)
функции, а вместо этого пытается и ошибки на template < int line, typename Arg1, void Func(Arg1) >
.
Если я прокомментирую позже, то он компилируется в порядке, поэтому способен найти прежнюю перегрузку.
Я попытался решить эту проблему в многочисленных образом, никто не работал, как мне нужно, чтобы «захватить» указатель на функцию в той же функции подписи Var (*) (const FuncArgs &)
Я предпочел бы не писать подпись функция в макросе. Кроме того, этот код по-прежнему не работает в VS2010 с ошибкой 'error C2440: typecast не может преобразовать из« перегруженной функции »в Var (*) (const FuncArgs &)' – xryl669
Хорошо, исправлена последняя ошибка, заменив ссылки на указатели на функция. VS2010, похоже, рассматривает тип 'Ret (&) (Arg)' (вместо 'Ret (*) (Arg)', даже если он был создан с помощью '& func' – xryl669