标签分发中的转发参数

forwarding parameters in tag dispatching

我正在编写用于绑定 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 方法都会导致编译错误:

error: no matching function for call to 'forward(int&)'
error: no matching function for call to 'forward(std::basic_string&)'

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

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

您需要将推导的类型传递给 std::forward()。在您的情况下,您将使用 std::forward<T>(param).