C++ 如何处理const&;及T&&;实例化到同一个签名?

C++ 如何处理const&;及T&&;实例化到同一个签名?,c++,templates,overload-resolution,C++,Templates,Overload Resolution,基本上,我想从常量左值版本和右值引用版本提供构造: transform_iterator(const Functor& f, const Iterator& it) : functor(f), iterator(it) {} transform_iterator(Functor&& f, Iterator&& it) : functor(f),

基本上,我想从常量左值版本和右值引用版本提供构造:

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

    transform_iterator(Functor&& f, Iterator&& it) :
            functor(f),
            iterator(it)
    {}
据我所知,右值引用版本不是通用引用。尽管如此,在这个呼叫站点上:

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
其中
v
output
都是int和double的向量,
window\u length
std::size\u 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());
std::向量v{“23”、“25”、“27”}//只是随机数
向量输出(v.size());
自动字符串_到_int=[](常量std::string&x)
{
返回std::stoi(x);
};
自动转换迭代器=shino::transformer(string_to_int,output.begin());
问题:如何修复它?

auto iterator = shino::transformer(divide, d_first);
您总是要调用函数的常量左值引用重载。原因是
d_first
是一个命名变量。这意味着它是一个
左值
,即使它作为右值传递到函数中。如果要使命名变量成为右值,需要使用
std::move
like

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

您总是要调用函数的常量左值引用重载。原因是
d_first
是一个命名变量。这意味着它是一个
左值
,即使它作为右值传递到函数中。如果要使命名变量成为右值,需要使用
std::move
like

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

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

您在发布的代码中的任何地方都没有使用右值调用
transform\u iterator::transform\u iterator


要调用右值引用重载,您需要一个右值
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

有关问题:


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

您在发布的代码中的任何地方都没有使用右值调用
transform\u iterator::transform\u iterator


要调用右值引用重载,您需要一个右值
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

有关问题:


正在使用右值调用
transform\u迭代器
的位置?@VittorioRomeo,已更新。您仍然没有传递任何右值
iterator
是一个左值,就像
d_first
一样。您是否忘记了一个
std::move
?@VittorioRomeo,这可能是因为
shino::transformer()
?没有其他地方可以让我通过右值。@FloHe:move constructor(移动构造函数)在哪里提到过?用右值调用
transform\u迭代器
在哪里?@VittorioRomeo,已更新。你仍然没有通过任何右值
iterator
是一个左值,就像
d_first
一样。您是否忘记了一个
std::move
?@VittorioRomeo,这可能是因为
shino::transformer()
?我没有其他地方经过右值。@FloHe:“移动构造函数”是在哪里提到的?