Hãy tưởng tượng chúng ta có tình huống sau đây:Tại sao std :: copy_if chữ ký không hạn chế các loại vị
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;
}
Cả hai cuộc gọi đến std::copy_if
tạo ra một lỗi biên dịch, vì sự quá tải đúng predicate()
chức năng không thể được infered bởi trình biên dịch kể từ khi std::copy_if
mẫu chữ ký chấp nhận bất kỳ loại ngữ:
template<typename _IIter,
typename _OIter,
typename _Predicate>
_OIter copy_if(// etc...
tôi thấy độ phân giải quá tải làm việc nếu tôi quấn std::copy_if
cuộc gọi vào một constra hơn chức năng mẫu ined:
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);
}
Câu hỏi của tôi là: tại sao STL không bị hạn chế như thế này? Từ những gì tôi đã thấy, nếu loại _Predicate
không phải là một hàm trả về bool
và chấp nhận loại đầu vào được lặp lại, nó sẽ tạo ra lỗi trình biên dịch. Vậy tại sao không đặt giới hạn này trong chữ ký, để độ phân giải quá tải có thể hoạt động?
hạn chế của bạn quá mạnh ('const' không bắt buộc, một số chuyển đổi được phép (' int' cho 'bool')). 'decltype' sẽ cho phép yêu cầu đúng (hoặc Khái niệm), nhưng phương thức đó đã được thực hiện trước C++ 11. – Jarod42