簡體   English   中英

基於范圍的For循環和ADL

[英]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編譯器的錯誤?

您必須將beginend放在Foo名稱空間中才能使ADL正常工作。 這是因為ADL將查找相應參數的名稱空間以搜索beginend定義。

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:不考慮全局命名空間的beginend的原因是因為更新的標准說在關聯的命名空間中查找了beginend ,但是沒有執行普通的不合格的查找。 這是標准中錯誤修復的結果( http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1442 )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM