Đây là một phần mở rộng cho câu hỏi này từ năm 2011: Range-based for loops and ADLPhạm vi-Based Đối Loop và ADL
Sử dụng Visual Studio 2015, tôi không thể đưa ra một loạt dựa trên vòng lặp for cho một Argument chứa tùy chỉnh sử dụng Dependent Lookup (ADL).
Tôi đã thực hiện một trường hợp thử nghiệm rất đơn giản dưới đây với một container tùy chỉnh:
#include <vector>
namespace Foo
{
template <typename T>
class Container
{
public:
std::vector<T> values;
};
}
template <typename T>
typename std::vector<T>::iterator begin(Foo::Container<T>& foo)
{
return foo.values.begin();
}
template <typename T>
typename std::vector<T>::iterator end(Foo::Container<T>& foo)
{
return foo.values.end();
}
Sử dụng thùng chứa này và ADL, các thử nghiệm sau biên dịch hoàn toàn tốt đẹp:
int main(int argc, char* argv[])
{
Foo::Container<int> values;
for (auto it = begin(values); it != end(values); ++it)
{
...
}
return 0;
}
như nó phải. Tôi không chắc liệu ADL có được sử dụng ở đây hay không, nhưng không quan tâm, nó có ý nghĩa. Từ MSDN documentation, ta có:
Hãy ghi nhớ những sự thật về phạm vi có trụ sở tại: mảng
Tự động nhận ra.
Nhận dạng các vùng chứa có .begin() và .end().
Sử dụng tra cứu phụ thuộc vào đối số bắt đầu() và kết thúc() cho bất kỳ mục đích nào khác.
Từ những gì tôi hiểu của ADL, và các tài liệu trên, sau đây cũng nên biên dịch:
int main(int argc, char* argv[])
{
Foo::Container<int> values;
for (auto value : values)
{
...
}
return 0;
}
Nhưng nó không. Thay vào đó, tôi nhận được các lỗi sau:
error C3312: no callable 'begin' function found for type 'Foo::Container<int>'
error C3312: no callable 'end' function found for type 'Foo::Container<int>'
Vậy điều gì đang xảy ra ở đây? Là giải thích của tôi về ADL không chính xác, hoặc là một lỗi với MSVC 14.0 Compiler?
IINM 'begin()' và 'end()' phải ở trong 'Foo'. – Quentin
Điều này không phụ thuộc vào ADL vì 'begin' và' end' không nằm trong vùng tên 'Foo', nhưng có vẻ như nó hoạt động tốt trong gcc: http://coliru.stacked-crooked.com/a/12047609140d05a9. Nếu bạn thay đổi 'begin' và' end' để thay thế 'const' ref, nó có hoạt động trên MSVC không? – rici
@rici, Không, không. Nó làm cho tôi tự hỏi tại sao nó hoạt động trong GCC mặc dù câu trả lời của Pavlo là đúng. Trình biên dịch nào là đúng?:) – Zeenobit