我有这样的代码,在我测试的所有编译器中编译罚款,除了VS2010。 我试图不在这里使用C ++ 11特定的功能,所以它仍然可以在过时的编译器上编译,如gcc 4.1。
#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
的{{1}}以前的定义int testFunc(void)
,而是template < int line, typename Arg1, void Func(Arg1) >
上的尝试和错误。
如果我对后面的内容进行评论,那么它编译得很好,所以能够找到前一个重载。
我试图以多种方式解决这个问题,没有工作,因为我需要在同一个签名函数中“捕获”指向函数的指针Var (*) (const FuncArgs &)
答案 0 :(得分:1)
您可以尝试使用通用模板函数并使用结构专门化,例如:
namespace detail
{
// class to specialize for each function type
template <int line, typename F, F f> struct helper_wrapper;
// partial specialization
template <int line, typename Ret, Ret (&Func)()>
struct helper_wrapper<line, Ret (&)(void), Func>
{
Var operator()(const FuncArgs&) const
{
Var ret;
ret = Func();
return ret;
}
};
// partial specialization
template <int line, void (&Func)()>
struct helper_wrapper<line, void (&)(), Func>
{
Var operator()(const FuncArgs&) const
{
Var ret;
Func();
return ret;
}
};
// partial specialization
template <int line, typename Ret, typename Arg1, Ret (&Func)(Arg1)>
struct helper_wrapper<line, Ret (&)(Arg1), Func>
{
Var operator()(const FuncArgs&) const
{
Var ret;
Arg1 arg;
ret = Func(arg);
return ret;
}
};
// partial specialization
template <int line, typename Arg1, void (&Func)(Arg1)>
struct helper_wrapper<line, void (&)(Arg1), Func>
{
Var operator()(const FuncArgs&) const
{
Var ret;
Arg1 arg;
Func(arg);
return ret;
}
};
// other partial specialization omitted.
}
// The general function
template <int line, typename F, F f>
Var WrapFuncT(const FuncArgs& arg) { return detail::helper_wrapper<line, F, f>()(arg); }
// The helper macro
#define WrapFunc(X, Y) &WrapFuncT<__LINE__, X, Y>
然后这样称呼它:
a = WrapFunc(int(&)(), testFunc);
b = WrapFunc(void(&)(int), testFunc2);