C++ 为什么赢了';这个模板不能编译吗?

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) { }

我在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)
    {
    }

    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.如果是这样的话,有没有办法通过电话会议?