[英]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
。
相同的推理適用於pointer
和reference_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.