如何处理 const T& 和 T&& 实例化到同一个签名?

How to deal with const T& and T&& instantiating to the same signature?

本文关键字:实例化 同一个 何处理 处理 const      更新时间:2023-10-16

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

    transform_iterator(const Functor& f, const Iterator& it) :
            functor(f),
            iterator(it)
    {}
    transform_iterator(Functor&& f, Iterator&& it) :
            functor(f),
            iterator(it)
    {}

据我所知,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

编译器说,rvalue参考版本最终是const lvalue参考版本。

为了完整性,这是sliding_average

的呼叫网站
sliding_average(v.begin(), v.end(), window_length, output.begin());

voutput都是int和双打的向量,而 window_lengthstd::size_t

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

另外,此代码对两个构造函数毫无问题地编译:

std::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());

问题:如何修复它?

我认为您对 lvalue s和 rvalue s的理解是不正确的。

您不是使用 rvalue 在您发布的代码中的任何地方调用transform_iterator::transform_iterator


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

要调用 rvalue参考过载,您需要一个 rvalue std::move可用于将d_first施加到 rvalue参考 - 示例:

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

相关问题:

  • " C 11 lvalue,rvalue and std :: move()"

  • "什么是RVALUES,LVALUES,XVALUES,GLVALUES和PRVALUES?"

in

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

您始终将调用函数的const lvalue参考过载。原因是d_first是命名变量。这意味着它是lvalue,即使它被作为RVALUE传递到功能中。如果要使命名变量成为rvalue,则需要使用 std::move

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