C++ 为什么赢了';这个模板不能编译吗?
我在MSVC2013更新4中使用了以下类:C++ 为什么赢了';这个模板不能编译吗?,c++,templates,C++,Templates,我在MSVC2013更新4中使用了以下类: template <typename T> class MyFunction; template<typename R, class... Ts> class MyFunction < R(Ts...) > { public: using func_type = R(*)(Ts...); MyFunction(func_type f) : m_func(f) { }
template <typename T>
class MyFunction;
template<typename R, class... Ts>
class MyFunction < R(Ts...) >
{
public:
using func_type = R(*)(Ts...);
MyFunction(func_type f)
: m_func(f)
{
}
R operator()(Ts ... args)
{
return m_func(args...);
}
private:
func_type m_func;
};
模板
类MyFunction;
模板
类MyFunction
{
公众:
使用func_type=R(*)(Ts…);
MyFunction(函数类型f)
:m_func(f)
{
}
R运算符()(Ts…args)
{
返回m_func(参数…);
}
私人:
func_类型m_func;
};
如果我这样使用它:
MyFunction<int (int)> f1(nullptr);
MyFunction<int __cdecl(int)> f2(nullptr);
MyFunction<int __stdcall(int)> f3(nullptr);
MyFunction f1(nullptr);
MyFunction f2(nullptr);
MyFunction f3(nullptr);
为什么f3无法编译?(考虑到cdecl是有效的!)
错误C2079:“f3”使用未定义的类“MyFunction”
错误C2440:“正在初始化”:无法从“nullptr”转换为“int”
在MSVC中,调用约定是函数类型的一部分;默认的调用约定是\uuu cdecl
,因此R(Ts..)
实际上是R\uu cdecl(Ts..)
并且与int\uu stdcall(int)
不匹配
如果您使用/Gz
进行编译,这使默认的调用约定成为\uu stdcall
,那么您将在f2
上看到一个错误
您必须为要支持的所有调用约定编写部分专门化:
template<class F, class R, class... Args>
class MyFunctionImpl {
public:
using func_type = F*;
MyFunctionImpl(func_type f)
: m_func(f)
{
}
R operator()(Args ... args)
{
return m_func(args...);
}
private:
func_type m_func;
};
template<typename R, class... Ts>
class MyFunction < R __cdecl(Ts...) >
: MyFunctionImpl<R __cdecl(Ts...), R, Ts...> {
using MyFunctionImpl<R __cdecl(Ts...), R, Ts...>::MyFunctionImpl;
};
template<typename R, class... Ts>
class MyFunction < R __stdcall(Ts...) >
: MyFunctionImpl<R __stdcall(Ts...), R, Ts...> {
using MyFunctionImpl<R __stdcall(Ts...), R, Ts...>::MyFunctionImpl;
};
// etc.
模板
类MyFunctionImpl{
公众:
使用func_type=F*;
MyFunctionImpl(函数类型f)
:m_func(f)
{
}
R运算符()(Args…Args)
{
返回m_func(参数…);
}
私人:
func_类型m_func;
};
模板
类MyFunction
:MyFunctionImpl{
使用MyFunctionImpl::MyFunctionImpl;
};
模板
类MyFunction
:MyFunctionImpl{
使用MyFunctionImpl::MyFunctionImpl;
};
//等等。
在MSVC中,调用约定是函数类型的一部分;默认的调用约定是\uuu cdecl
,因此R(Ts..)
实际上是R\uu cdecl(Ts..)
并且与int\uu stdcall(int)
不匹配
如果您使用/Gz
进行编译,这使默认的调用约定成为\uu stdcall
,那么您将在f2
上看到一个错误
您必须为要支持的所有调用约定编写部分专门化:
template<class F, class R, class... Args>
class MyFunctionImpl {
public:
using func_type = F*;
MyFunctionImpl(func_type f)
: m_func(f)
{
}
R operator()(Args ... args)
{
return m_func(args...);
}
private:
func_type m_func;
};
template<typename R, class... Ts>
class MyFunction < R __cdecl(Ts...) >
: MyFunctionImpl<R __cdecl(Ts...), R, Ts...> {
using MyFunctionImpl<R __cdecl(Ts...), R, Ts...>::MyFunctionImpl;
};
template<typename R, class... Ts>
class MyFunction < R __stdcall(Ts...) >
: MyFunctionImpl<R __stdcall(Ts...), R, Ts...> {
using MyFunctionImpl<R __stdcall(Ts...), R, Ts...>::MyFunctionImpl;
};
// etc.
模板
类MyFunctionImpl{
公众:
使用func_type=F*;
MyFunctionImpl(函数类型f)
:m_func(f)
{
}
R运算符()(Args…Args)
{
返回m_func(参数…);
}
私人:
func_类型m_func;
};
模板
类MyFunction
:MyFunctionImpl{
使用MyFunctionImpl::MyFunctionImpl;
};
模板
类MyFunction
:MyFunctionImpl{
使用MyFunctionImpl::MyFunctionImpl;
};
//等等。
nullptr!=空
。想想看。构造函数采用func_类型,这是一个函数指针,因此nullptr可以吗?我怀疑R(Ts…)
是隐式R\uu cdecl(Ts…)
,因此部分专门化与int\uu stdcall(int)
不匹配。还要注意,f1和f2是编译的,只有f3有一个issue@T.C.如果是这样,是否有某种方法可以在?nullptr!=空
。想想看。构造函数采用func_类型,这是一个函数指针,因此nullptr可以吗?我怀疑R(Ts…)
是隐式R\uu cdecl(Ts…)
,因此部分专门化与int\uu stdcall(int)
不匹配。还要注意,f1和f2是编译的,只有f3有一个issue@T.C.如果是这样的话,有没有办法通过电话会议?