簡體   English   中英

ADL with std :: function:可以通過std :: function的參數列表中的類型找到帶std :: function對象的函數嗎?

[英]ADL with std::function: Can functions taking std::function objects be found via the types in the std::function's argument list?

請考慮以下代碼段:

#include <functional>

namespace ns {
    struct Arg{};
    using Func = std::function<int(Arg)>;

    Func operator+(Func lhs, Func rhs) {
        return [lhs, rhs](Arg arg) {
            return lhs(arg) + rhs(arg);
        };
    }
}

int main() {
    ns::Func foo = [](ns::Arg i) {return 5;};
    ns::Func bar = [](ns::Arg i) {return 2;};
    auto foobar = foo + bar;
    return foobar(ns::Arg());
}

上面的代碼匯編了各種編譯器。 相反,以下代碼片段無法編譯。 唯一的區別是FuncArg vs int )中使用的參數類型:

#include <functional>

namespace ns {
    using Func = std::function<int(int)>;

    Func operator+(Func lhs, Func rhs) {
        return [lhs, rhs](int i) {
            return lhs(i) + rhs(i);
        };
    }
}

int main() {
  ns::Func foo = [](int i) {return i + 5;};
  ns::Func bar = [](int i) {return i * 2;};
  auto foobar = foo + bar; // BANG! Error here!
  return foobar(2);
}

我理解后一個版本的錯誤:被調用的operator+在命名空間中定義,因此在沒有明確指定命名空間的情況下找不到。 依賴於參數的查找在這里沒有用,因為operator+是在與參數類型不同的命名空間( ns )中定義的( std::functionnamespace std定義, using聲明與此無關)。

但是為什么在Func采用參數ns::Arg的情況下找到正確的operator+ Func的命名空間沒有改變。 使用Arg的代碼是否符合C ++標准?

使用Arg的代碼是否符合C ++標准?

它是。 根據[basic.lookup.argdep / 2.2] ,ADL的關聯命名空間包括專門化的任何模板參數的關聯命名空間。

...此外,如果T是類模板特化,其關聯的名稱空間和類還包括:與模板類型參數(模板模板參數除外)提供的模板參數類型相關聯的名稱空間和類; 任何模板模板參數都是成員的名稱空間; 以及用作模板模板參數的任何成員模板的類都是成員。 [注意:非類型模板參數不會對關聯的命名空間集合產生影響。 - 結束說明]

std::function<int(Arg)>是一個類模板特化, ns與其中一個參數相關聯。 因此, ns包含在由ADL搜索operator+的命名空間集中。

存在此規則是為了使可重用組件更有用。 我們的想法是允許庫公開一個API,它將std::unique_ptr<ns::Foo>作為句柄類型,並且當呈現句柄時,ADL從ns獲取正確的函數。

暫無
暫無

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

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