簡體   English   中英

考慮模板參數的參數依賴外觀(ADL)?

[英]Argument Dependent Look (ADL) considering template arguments?

我有幾個命名空間,每個命名空間都有一個名為f的函數模板。

// f() and Widget
namespace A {
  struct Widget { };

  template <typename T>
  void func(const T&) { }
}

// f() and caller()
namespace B {
  template <typename T>
  void func(const T&) { }

  template <typename T>
  void caller(const T& t) {
    func(t); // error occurs here
  }
}

template <typename T>
class Wrap { };

int main() {
  Wrap<A::Widget> w{};
  B::caller(w); // triggers error
}

上面產生以下錯誤

error: call of overloaded ‘func(const Wrap<A::Widget>&)’ is ambiguous
     func(t);
     ~~~~^~~
note: candidate: void B::func(const T&) [with T = Wrap<A::Widget>]
   void func(const T&) { }
        ^~~~
note: candidate: void A::func(const T&) [with T = Wrap<A::Widget>]
   void func(const T&) { }
        ^~~~

如果Wrap在全局名稱空間中,為什么要考慮A::func B::caller不應該呼叫B::func嗎?

在模板的情況下,ADL不僅考慮了函數的參數。 在這里,您將Wrap<A::Widget>作為B::caller的參數。 因為callernamespace B ,所以顯然考慮了B::func 考慮A::func的原因來自以下(添加了重點)

N659 6.4.2 /(2.2)[basic.lookup.argdep]

如果T是一個類類型(包括並集),則其關聯的類為:類本身; 它所屬的類(如果有); 及其直接和間接基類。 其關聯的名稱空間是其關聯類的最內部封閉的名稱空間。 此外,如果T是類模板專業化,則其關聯的名稱空間和類還包括:與為模板類型參數提供的模板參數類型相關的名稱空間和類 [...]

因為A::WidgetWrap的模板參數,所以A也是Wrap<A::Widget>的關聯命名空間

通過使用限定名稱來防止ADL,可以使此示例按預期進行編譯:

template <typename T>    
void caller(const T& t) {    
  B::func(t);      
}

或將函數名稱括在parethese中

template <typename T>    
void caller(const T& t) {    
  (func)(t);      
}

暫無
暫無

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

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