C++ 这是编写接受具有可变参数数的函数指针的函数模板的正确方法吗?

C++ 这是编写接受具有可变参数数的函数指针的函数模板的正确方法吗?,c++,templates,function-pointers,variadic-templates,C++,Templates,Function Pointers,Variadic Templates,我有以下代码 class ODBCFuncCall // Line 67 { public: ODBCFuncCall(SQLHANDLE stmt, SQLHANDLE conn) : m_stmt(stmt), m_conn(conn) {} virtual ~ODBCFuncCall() {} template <typename... A> void RunStatementFunction(SQLRETURN (*in_func)(SQL

我有以下代码

class ODBCFuncCall // Line 67
{
public:
    ODBCFuncCall(SQLHANDLE stmt, SQLHANDLE conn) : m_stmt(stmt), m_conn(conn) {}

    virtual ~ODBCFuncCall() {}

    template <typename... A>
    void RunStatementFunction(SQLRETURN (*in_func)(SQLHSTMT, A...), A... args)
    {
        in_func(m_stmt, args...);
    }

    virtual const char* GetFunctionName() = 0;

    virtual void Setup() = 0;
    virtual void Run() = 0;
    virtual void Cleanup() = 0;

protected:
    const SQLHANDLE m_stmt;
    const SQLHANDLE m_conn;
};
当我注释掉“RunStatementFunction”时,它编译得很好。 从我在谷歌上搜索到的类似内容来看,语法似乎是正确的…

是的,这是正确的:

使用2012年11月CTP时,可变模板仅在VS 2012中可用。这引入了一个单独的工具集,必须在项目属性中选择该工具集。它应该用它编译。

是的,这是正确的:


使用2012年11月CTP时,可变模板仅在VS 2012中可用。这引入了一个单独的工具集,必须在项目属性中选择该工具集。它应该用它来编译。

我看到了两个问题。第一个vs2012不支持可变模板,在实验性CTP之外,不应在生产代码中使用

其次,应该将参数完美地转发到函数指针

template <typename... As,typename...Ts>
void RunStatementFunction(SQLRETURN (*in_func)(SQLHSTMT, As...), Ts&&... args) 
{
  in_func(m_stmt, std::forward<Ts>(args)...);
}
模板
void runstatement函数(SQLRETURN(*in_func)(SQLHSTMT,As…,Ts&…args)
{
in_func(m_stmt,std::forward(args)…);
}
这将消除优化构建中辅助函数的所有开销


vs2013支持可变模板。

我看到两个问题。第一个vs2012不支持可变模板,在实验性CTP之外,不应在生产代码中使用

其次,应该将参数完美地转发到函数指针

template <typename... As,typename...Ts>
void RunStatementFunction(SQLRETURN (*in_func)(SQLHSTMT, As...), Ts&&... args) 
{
  in_func(m_stmt, std::forward<Ts>(args)...);
}
模板
void runstatement函数(SQLRETURN(*in_func)(SQLHSTMT,As…,Ts&…args)
{
in_func(m_stmt,std::forward(args)…);
}
这将消除优化构建中辅助函数的所有开销


vs2013支持可变模板。

是的,这是正确的。根据bah的说法,可变模板在VS2012中不可用,但在VS2013中可用,谢谢。我以为它们是在VS2012中引入的。哦,是的,这是正确的。根据bah的说法,可变模板在VS2012中不可用,但在VS2013中可用,谢谢。我以为它们是在VS2012中引入的。哦,好吧,谢谢你的提示。完美转发在我的例子中没有帮助,因为这将用于ODBC函数,这些函数都采用有效复制的参数。@b如果
A
s是值类型,则原始代码将复制它们两次。如果它们的复制成本很低,好吗:但为什么要依赖它呢?@Yakk,我相信编译器会优化掉一个原语类型的副本,如果可能的话。不过总的来说,你说的很有道理。谢谢你的提示。完美转发在我的例子中没有帮助,因为这将用于ODBC函数,这些函数都采用有效复制的参数。@b如果
A
s是值类型,则原始代码将复制它们两次。如果它们的复制成本很低,好吗:但为什么要依赖它呢?@Yakk,我相信编译器会优化掉一个原语类型的副本,如果可能的话。但总的来说,你所说的是有道理的。