H Bellamy
H Bellamy

Reputation: 22725

Visual C++ reports an ambiguous symbol error for non-ambiguous class

Consider the following C++ code,

namespace {
  class ExprParentFinder {
    friend class CodeCompletionTypeContextAnalyzer;
  };
}

class CodeCompletionTypeContextAnalyzer {
public:
  CodeCompletionTypeContextAnalyzer() {}
};

int main() {
  CodeCompletionTypeContextAnalyzer TypeAnalyzer;
  return 0;
}

This compiles fine with Clang/GCC. However, MSVC chokes, and reports

1> ConsoleApplication2.cpp

1> consoleapplication2.cpp(29): error C2872: 'CodeCompletionTypeContextAnalyzer': ambiguous symbol

1> consoleapplication2.cpp(23): note: could be 'CodeCompletionTypeContextAnalyzer'

1> consoleapplication2.cpp(19): note: or '`anonymous-namespace'::CodeCompletionTypeContextAnalyzer'

Is CodeCompletionTypeContextAnalyzer TypeAnalyzer really ambiguous here from a C++ standards point of view, or is this an MSVC bug. If so, what's causing this error.

The work around is to change the code to

int main() {
  ::CodeCompletionTypeContextAnalyzer TypeAnalyzer;
  return 0;
}

Upvotes: 3

Views: 1458

Answers (1)

T.C.
T.C.

Reputation: 137404

This is well-formed (i.e., MSVC bug) but unlikely to be what you actually want. [namespace.memdef]/3, footnote omitted:

If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup ([basic.lookup.unqual]) or qualified lookup ([basic.lookup.qual]).

friend class CodeCompletionTypeContextAnalyzer; declares CodeCompletionTypeContextAnalyzer to be a member of the unnamed namespace, but that name is not visible to name lookup.

Then, class CodeCompletionTypeContextAnalyzer { /* ... */ }; declares (and defines) a different class also called CodeCompletionTypeContextAnalyzer as a member of the global namespace; this class is not a friend of ExprParentFinder.

Because the unnamed namespace's CodeCompletionTypeContextAnalyzer isn't visible to name lookup, the only CodeCompletionTypeContextAnalyzer that can be found is the second one, and there is no ambiguity.

Upvotes: 3

Related Questions