2017-02-21 65 views
0

基本上我想从常量左值版本和右值引用的版本提供施工:如何处理const T&和T &&实例化相同的签名?

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 

编译器说,右值引用的版本最终被const的左值参考版本。

为了完整起见,这里的sliding_average

sliding_average(v.begin(), v.end(), window_length, output.begin()); 

其中两个voutput是int和double型向量调用点,并window_lengthstd::size_t

当我删除常量左值版本,代码编译和工作正常。

而且,这个代码没有问题编译与两个构造函数:

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

问题:如何解决?

+1

凡'transform_iterator'被称为有*右值*? –

+0

@VittorioRomeo,已更新。 – Incomputable

+1

你还没有通过* rvalue *。 'iterator'是* lvalue *,就像'd_first'一样。你忘了'std :: move'吗? –

回答

1

我认为你左值 S和右值 S的理解是不正确的。

你不是有右值在您发布代码的任何地方调用transform_iterator::transform_iterator


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

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

相关的问题:

1

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

你总是会调用该函数的常量左值参考超载。原因是d_first是一个命名变量。这意味着它是一个lvalue,即使它作为右值传递给函数。如果你想使一个名为变量右值,你需要使用std::move

auto iterator = shino::transformer(divide, std::move(d_first)); 
相关问题