【问题标题】:forwarding parameters in tag dispatching标签调度中的转发参数
【发布时间】:2015-12-30 08:30:08
【问题描述】:

我正在编写用于绑定 SQL 参数的函数,并希望使用标签调度。所以我写了这段代码:

class OraclePreparedStatement
{
public:
    template<typename T>
    void bind_param(uint32_t col_index, T&& param)
    {
        bind_param_impl(col_index, std::forward(param), 
                        std::is_integral<std::remove_reference_t<T>>());
    }

private:
    template<typename T>
    void bind_param_impl(uint32_t col_index, T&& param, std::true_type)
    {
        statement->setNumber(col_index, oracle::occi::Number(param));
    }

    template<typename T>
    void bind_param_impl(uint32_t col_index, T&& param, std::false_type)
    {
        statement->setString(col_index, std::forward(param));
    }

    OracleConnection::StatementWrapper statement;
};

然后我编写了以下客户端代码来测试它:

OraclePreparedStatement stmt;
auto col_index = 1;
stmt.bind_param(col_index++, 15);
stmt.bind_param(col_index++, std::string("test string"));

但是编译失败。两次调用 bind_param 方法都会导致编译错误:

错误:没有匹配的函数调用'forward(int&)'
错误:没有匹配函数调用'forward(std::basic_string&)'

为什么转发参数编译失败?

【问题讨论】:

    标签: c++ templates c++14 template-meta-programming perfect-forwarding


    【解决方案1】:

    std::forward 特意以这样一种方式编写,即您必须显式指定模板参数——没有它就不可能工作。所以就这样做吧:

    bind_param_impl(col_index, std::forward<T>(param), 
                    std::is_integral<std::remove_reference_t<T>>());
    

    statement->setString(col_index, std::forward<T>(param));
    

    原因是std::forward 要工作,它需要知道T 本身是否是一个引用。请注意,由于param 始终是一个左值,因此如果不授予T 的显式访问权限,就无法编写std::forward

    【讨论】:

    • 哦,当然,我的代码输入错误,我无法识别。谢谢。
    【解决方案2】:

    您需要将推导的类型传递给std::forward()。在您的情况下,您将使用std::forward&lt;T&gt;(param)

    【讨论】:

      猜你喜欢
      • 2014-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 1970-01-01
      • 2014-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多