代码之家  ›  专栏  ›  技术社区  ›  Destructor

不明确的成员模板查找

  •  4
  • Destructor  · 技术社区  · 6 年前

    答案是什么 question

    #include <vector>
    using std::vector;
    
    struct foo {
      template<typename U>
      void vector();
    };
    
    int main() {
      foo f;
      f.vector<int>(); // ambiguous!
    }
    

    main中的最后一行是不明确的,因为编译器不仅查找 vector foo main . 所以两者都找到了 std::vector foo::vector . 要解决这个问题,你必须写

    f.foo::vector<int>();
    

    我在所有流行的C++编译器上都尝试过这个程序。 g++ , clang++ , vc++ 英特尔C++和所有编译器都编译程序没有任何错误。那么,他为什么说这个节目有歧义呢?C++标准对此有何看法?

    1 回复  |  直到 6 年前
        1
  •  10
  •   Shafik Yaghmour    6 年前

    这是C++ 03中的情况,但是这是固定在C++ 11中的。我们甚至可以试试这个 live in godbolt with clang using -std=c++03 flag . 我们确实收到了一个警告:

    <source>:11:5: warning: lookup of 'vector' in member access expression is ambiguous; using member of 'foo' [-Wambiguous-member-template]
    
      f.vector<int>(); // ambiguous!
        ^
    

    旧的clang文档 using the same example from the defect report below 在描述警告时 -Wambiguous-member-template .

    这是通过 defect report 1111: Remove dual-scope lookup of member template names 这就解释了这个问题:

    在类成员访问表达式(8.2.5[expr.ref])中,如果。或->令牌后面紧跟一个标识符,后跟一个<, 必须查找标识符以确定;是 小于运算符。标识符首先在 对象表达式。如果找不到标识符,则返回 在整个后缀表达式的上下文中查找 命名类模板。如果对象类中的查找 表达式找到模板时,名称也会在上下文中查找 整个后缀表达式和

    • 如果找不到名称,则使用在对象表达式的类中找到的名称,否则

    • 如果名称是在整个后缀表达式的上下文中找到的,并且没有命名类模板,则 在对象的类中使用表达式,否则

    • 如果找到的名称是类模板,则该名称应引用与在对象表达式的类中找到的名称相同的实体,

    #include <set>
    using std::set;
    struct X {
      template <typename T> void set(const T& value);
    };
    void foo() {
      X x;
      x.set<double>(3.2);
    }
    

    在X的范围内查找,显然正确的分辨率是, 修复了析构函数名称的类似问题,但缺少成员