标签分派中的转发参数

时间:2015-12-30 08:30:09

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

我正在编写用于绑定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&amp;)'的匹配函数   错误:没有匹配函数来调用'forward(std :: basic_string&amp;)'

为什么转发参数无法编译?

2 个答案:

答案 0 :(得分:1)

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本身是否为引用。请注意,由于std::forward始终是左值,因此如果没有T明确访问select sensorNumber, timeOfReading from tablename group by sensorNumber, timeOfReading having count(distinct sensorValue)>1 ,就无法编写select t.* from tablename t inner join ( select sensorNumber, timeOfReading from tablename group by sensorNumber, timeOfReading having count(distinct sensorValue)>1 ) d on t.sensorNumber=d.sensorNumber and t.timeOfReading=d.timeOfReading

答案 1 :(得分:0)

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