如何应对const T&和T&&实例化到相同的签名?

时间:2017-02-21 15:01:20

标签: c++ templates overload-resolution

基本上我想提供const lvalue版本和rvalue参考版本的构造:

template <typename InputIt, typename OutputIt>
std::pair<InputIt, OutputIt> sliding_average(InputIt first, InputIt last,
                    const typename std::iterator_traits<InputIt>::difference_type window_length,
                    OutputIt d_first)
{
    using value_type = typename std::iterator_traits<InputIt>::value_type;
    auto divide = [&window_length](const value_type& value)
    {
        return value / window_length;
    };

    auto iterator = shino::transformer(divide, d_first); //transform_iterator<Functor, Iterator>

   shino::sliding_window(first, last, iterator, window_length);
                                       //^^ pass by value

据我所知,右值参考版本不是通用参考。尽管如此,在这个电话网站上:

sliding_average

编译器说rvalue引用版本最终是const lvalue引用版本。

为完整起见,这是sliding_average(v.begin(), v.end(), window_length, output.begin());

的呼叫网站
v

其中outputwindow_length都是int和double的向量,std::size_tstd::vector<std::string> v{"23", "25", "27"}; //just random numbers std::vector<int> output(v.size()); auto string_to_int = [](const std::string& x) { return std::stoi(x); }; auto conversion_iterator = shino::transformer(string_to_int, output.begin());

当我删除const lvalue版本时,代码编译并正常工作。

此外,此代码编译没有问题,两个构造函数:

{{1}}

问题:如何修复?

2 个答案:

答案 0 :(得分:1)

auto iterator = shino::transformer(divide, d_first);

您总是会调用函数的const左值引用重载。原因是d_first是一个命名变量。这意味着即使它作为右值传递给函数,它也是lvalue。如果要将命名变量设为右值,则需要使用std::move之类的

auto iterator = shino::transformer(divide, std::move(d_first));

答案 1 :(得分:1)

我认为您对左值右值的理解不正确。

您未在您发布的代码中的任何位置使用 rvalue 调用transform_iterator::transform_iterator

auto iterator = shino::transformer(divide, d_first);
//                                         ^^^^^^^
//                                         lvalue

要调用右值引用重载,您需要 rvalue std::move可用于将d_first转换为右值引用 - 示例:

auto iterator = shino::transformer(divide, std::move(d_first));
//                                         ^^^^^^^^^^^^^^^^^^
//                                         rvalue

这同样适用于您在编辑中添加的代码:

shino::sliding_window(first, last, iterator, window_length);
//                                 ^^^^^^^^
//                                 lvalue

你可能想要:

shino::sliding_window(first, last, std::move(iterator), window_length);
//                                 ^^^^^^^^^^^^^^^^^^^
//                                 rvalue

相关问题: