此question的答案在以下代码中表示:
#include <vector>
using std::vector;
struct foo {
template<typename U>
void vector();
};
int main() {
foo f;
f.vector<int>(); // ambiguous!
}
main中的最后一行是不明确的,因为编译器不仅在foo
中查找vector
,而且还从main
中开始查找非限定名称。因此,它可以同时找到std::vector
和foo::vector
。要修复此问题,您必须编写
f.foo::vector<int>();
我已经在所有流行的英特尔编译器( g++
、clang++
、vc++
和C++ C++ )上试用过此程序,所有编译器都编译此程序,没有任何错误。那么,他为什么说这个节目有歧义呢?C++标准对此有何规定?
发布于 2018-10-04 11:56:25
这是在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!
^
描述-Wambiguous-member-template
警告时的旧clang文档using the same example from the defect report below。
这是通过defect report 1111: Remove dual-scope lookup of member template names 更改的,它解释了这个问题:
根据6.4.5 basic.lookup.classref第1款,
在类成员访问表达式(8.2.5 expr.ref)中,如果.首先在对象表达式的类中查找标识符。如果没有找到标识符,则在整个后缀表达式的上下文中查找它,并命名一个类模板。如果在对象表达式的类中查找找到了模板,则还会在整个后缀表达式的上下文中查找该名称,并且
这使得以下内容格式不正确:
这是令人困惑和不必要的。编译器已经在X的作用域中进行了查找,显然正确的解决方案是它,而不是来自后缀表达式作用域的标识符。问题305修复了析构函数名称的类似问题,但缺少成员函数。
https://stackoverflow.com/questions/52638699
复制相似问题