假設我們想從一個向量int
s中刪除重複的值。通常的解決方案是對矢量進行排序並使用擦除刪除方式擦除重複項。但是我們需要維護不會被刪除的元素的順序,所以我們無法排序。所以有人會想出這樣的斷言,並使用與remove_if
算法:標準庫算法是否允許複製謂詞參數?
struct comp {
std::set<int> s;
comp() : s() {}
bool operator()(int i)
{
return !(s.insert(i)).second;
}
};
但是,這將打破,如果謂詞對象將被複製出於某種原因,因爲我們將得到set
成員的兩個副本。事實上,海灣合作委員會的執行remove_if
正是這麼做的:
template<typename _ForwardIterator, typename _Predicate>
_ForwardIterator
remove_if(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
{
__first = _GLIBCXX_STD_A::find_if(__first, __last, __pred);
if(__first == __last) // ^^^^^ here a copy is made
return __first;
_ForwardIterator __result = __first;
++__first;
for(; __first != __last; ++__first)
if(!bool(__pred(*__first)))
{
*__result = _GLIBCXX_MOVE(*__first);
++__result;
}
return __result;
}
的解決辦法是讓我們的仿函數靜態的set
成員:
struct comp {
static set<int> s;
comp() { s. clear(); }
bool operator()(int i)
{
return !(s.insert(i)).second;
}
};
set<int> comp::s;
但問題依然存在:
難道我們需要確保謂詞仿函數的可能副本不會破壞我們的邏輯? 標準中是否有任何規定(或禁止)關於此問題的某些行爲?或者它是實施中的錯誤?
+1關於純功能和良好參考的好處。 – juanchopanza
有標準指定順序的算法。像'std :: copy',不是?標準中的「備註:穩定」是什麼意思,是不是要求訂單得到保留? – jrok
@jrok:只有在保留元素的相對順序不會改變的意義上,它纔是穩定的,而不是OP所希望的。 (並且'copy'不帶謂詞,'copy_if'不帶謂詞,'copy_if'只帶一個,但沒有指定它的應用順序。) –