[英]Range-Based For Loop and ADL
這是2011年這個問題的擴展: 基於范圍的for循環和ADL
使用Visual Studio 2015,我無法使用Argument Dependent Lookup(ADL)為自定義容器創建基於范圍的for循環。
我在下面用一個自定義容器做了一個非常簡單的測試用例:
#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();
}
使用此容器和ADL,以下測試編譯完全正常:
int main(int argc, char* argv[])
{
Foo::Container<int> values;
for (auto it = begin(values); it != end(values); ++it)
{
...
}
return 0;
}
正如它應該。 我不確定ADL是否在這里使用,但無論如何,這都是有道理的。 從MSDN文檔中 ,我們有:
請記住有關基於范圍的這些事實:
自動識別數組。
識別具有.begin()和.end()的容器。
使用依賴於參數的查找begin()和end()用於其他任何事情。
根據我對ADL的理解以及上面的文檔,還應該編譯以下內容:
int main(int argc, char* argv[])
{
Foo::Container<int> values;
for (auto value : values)
{
...
}
return 0;
}
但事實並非如此。 相反,我得到以下錯誤:
error C3312: no callable 'begin' function found for type 'Foo::Container<int>'
error C3312: no callable 'end' function found for type 'Foo::Container<int>'
那么這里發生了什么? 我對ADL的解釋是否不正確,或者這是MSVC 14.0編譯器的錯誤?
您必須將begin
和end
放在Foo
名稱空間中才能使ADL正常工作。 這是因為ADL將查找相應參數的名稱空間以搜索begin
和end
定義。
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();
}
}
UPD:不考慮全局命名空間的begin
和end
的原因是因為更新的標准說在關聯的命名空間中查找了begin
和end
,但是沒有執行普通的不合格的查找。 這是標准中錯誤修復的結果( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.