簡體   English   中英

為什么back_insert_iterator / front_insert_iterator / insert_iterator的value_type / difference_type / pointer / reference都是無效的?

[英]Why the value_type/difference_type/pointer/reference of back_insert_iterator/front_insert_iterator/insert_iterator are all void?

在我的項目中,我想將流分割為某些給定類型的值,因此我將模板函數實現為

template <typename TElem, typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    TElem elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

我認為這很尷尬,因為我必須在調用它時明確給出TElem的類型。 例如,我必須寫:

std::vector<int> v;
SplitSpace<int>(std::cin, back_inserter(v));
// I want to it to be   SplitSpace(std::cin, back_inserter(v)); 

我試圖從(模板)迭代器獲取值類型並使用std::iterator_traits ,如下所示:

template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    typename std::iterator_traits<TOutputIter>::value_type elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

但是,上述代碼不適用於back_insert_iterator 我檢查了std命名空間中back_insert_iterator/front_insert_iterator/insert_iterator的源代碼,發現value_type/difference_type/pointer/reference都是void

我想知道為什么這些類型都void ,有什么考慮嗎? 另一個問題是,是否可以在調用它時實現SplitSpace函數而不顯式給出元素類型? 謝謝。

value_type在OutputIterators的情況下沒有多大意義,因為輸出迭代器不允許訪問任何值,更重要的是它可以接受各種值類型。

用於輸出迭代的唯一要求it是它必須支持該表達*it = o 其中o是一些類型,它是在該組的該可寫的特定迭代器類型i的類型的值 (§24.2.1)。 這意味着輸出迭代器可以接受多種類型:例如,它的operator*可以返回一個代理對象,該對象為各種類型的operator=重載; 在這種情況下應該是value_type

例如,考慮以下輸出迭代器:

struct SwallowOutputIterator : 
    public std::iterator<output_iterator_tag, void, void, void, void>
{
    struct proxy // swallows anything
    {
        template <typename T>
        void operator=(const T &) {}
    };

    proxy operator*() 
    {
        return proxy();
    }

    // increment operators
};

這里沒有值得選擇的value_type

相同的推理適用於pointerreference_type difference_type未定義,因為您無法計算兩個輸出迭代器之間的距離,因為它們是單遍的。

注意:標准明確規定insert_iterator及其兄弟insert_iterator必須繼承自iterator<output_iterator_tag, void, void, void, void> ,因此這不是您實現的特性。

如果您只是想要一種避免指定TElem模板參數的方法,可以使用以下方法:

template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    typedef typename TOutputIter::container_type::value_type TElem;

    TElem elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

...當然,根據您假裝使用的TOutputIter類型,您不應使用此方法。

正如Luc在評論中所提到的,您可以使用標准庫輕松完成您想要做的事情:

std::vector<int> v;
std::copy( std::istream_iterator( std::cin )
         , std::istream_iterator()
         , std::back_inserter( v ) );

AFAIK,你應該能夠從迭代器中獲取container_type ,從中你應該能夠獲得value_type 你可能想在某個時候專注於一pair 這應該回答第二部分,第一部分; 不確定...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM