2015-10-14 80 views
3

C++標準庫包含方便的模板類std::move_iterator。鑑於std::movestd::forward之間的密切關係,爲什麼沒有相應的std::forward_iterator?用法示例:forward_iterator模板類是否有意義?

template <typename C> 
auto foo(C&& values) 
{ 
    remove_reference_t<C> result {}; 
    result.reserve(values.size()); 
    std::transform(std::make_forward_iterator<C>(std::begin(values)), 
        std::make_forward_iterator<C>(std::end(values))), 
        std::back_inserter(result), Bar()); 
    return result; 
} 

的想法是我現在可以使用foo,如:

std::vector<ComplexType> values {/* lots of values */}; 

auto copied_fooed = foo(values); 
// or 
auto moved_fooed = foo(std::move(values)); 

而不必寫兩個foo秒。

+1

正確的名稱應該是'std :: forwardable_iterator'以避免與經典的Forward Iterator衝突。 – 101010

+0

@ Jarod42謝謝。固定(我認爲)。 – Daniel

+0

你問你爲什麼沒有一個(提出建議?)或者如何寫一個? – Barry

回答

1

我無法回答爲什麼這樣的事情不存在。但這當然是可以實施的。基本上,您的C類型是左值引用(在這種情況下只是通過參數)或它不是引用(在這種情況下,使用std::make_move_iterator)。

首先,讓我們開始一個偉大的除了任何工具,almost static if(輕微改變):

namespace detail { 
    enum class enabler {}; 
} 

template <bool B> 
using EnableIf = std::enable_if_t<B, detail::enabler>; 

現在我們只使用SFINAE在兩個重載:

template <typename C, 
      typename Iterator, 
      EnableIf<std::is_lvalue_reference<C>::value>...> 
Iterator make_forward_iterator(Iterator i) 
{ 
    return i; 
} 

template <typename C, 
      typename Iterator, 
      EnableIf<!std::is_lvalue_reference<C>::value>...> 
auto make_forward_iterator(Iterator i) 
{ 
    return std::make_move_iterator(i); 
} 

或者,這可能更簡單,可能只是標籤發送:

namespace detail {  
    template <typename Iterator> 
    Iterator make_forward_iterator(Iterator i, std::true_type) 
    { 
     return i; 
    } 

    template <typename Iterator> 
    auto make_forward_iterator(Iterator i, std::false_type) 
    { 
     return std::make_move_iterator(i); 
    } 
} 

template <typename C, typename Iterator> 
auto make_forward_iterator(Iterator i) { 
    return detail::make_forward_iterator(i, std::is_lvalue_reference<C>{}); 
} 
1

它比這複雜一點。

擁有一個容器,容器的l/r值意味着移動迭代器可能有用。

但對於意見,這不起作用:從右值視圖移動是無主狀態的破壞性。

實際上,這意味着基於l/r值的決定是否與上下文和價值相互決定,這使得它很棘手。

Range-v3和概念可能會使這更容易推理。

相關問題