假設我們有以下的情況:爲什麼在std :: copy_if簽名不限制謂詞類型
struct A
{
int i;
};
struct B
{
A a;
int other_things;
};
bool predicate(const A& a)
{
return a.i > 123;
}
bool predicate(const B& b)
{
return predicate(b.a);
}
int main()
{
std::vector<A> a_source;
std::vector<B> b_source;
std::vector<A> a_target;
std::vector<B> b_target;
std::copy_if(a_source.begin(), a_source.end(), std::back_inserter(a_target), predicate);
std::copy_if(b_source.begin(), b_source.end(), std::back_inserter(b_target), predicate);
return 0;
}
兩個調用std::copy_if
產生編譯錯誤,因爲predicate()
功能的正確超載不能infered通過自std::copy_if
模板簽名,編譯器接受任何類型的謂詞:
template<typename _IIter,
typename _OIter,
typename _Predicate>
_OIter copy_if(// etc...
我發現,如果我換行std::copy_if
呼叫到一個更constra重載解析工作模板功能:
template<typename _IIter,
typename _OIter,
typename _Predicate = bool(const typename std::iterator_traits<_IIter>::value_type&) >
void copy_if(_IIter source_begin,
_IIter source_end,
_OIter target,
_Predicate pred)
{
std::copy_if(source_begin, source_end, target, pred);
}
我的問題是:爲什麼在STL中它是不是已經被這樣約束了?從我所看到的情況來看,如果_Predicate
類型不是返回bool
並且接受迭代的輸入類型的函數,它仍然會產生編譯器錯誤。那麼爲什麼不把這個限制放在簽名中,以便重載解析可以工作?
您的約束太強(不需要'const',允許一些轉換('int'到'bool'))。 'decltype'將允許正確的需求(或概念),但該方法在C++ 11之前完成。 – Jarod42