Microsoft KB Archive/814793

= You may receive a &quot;C3767&quot; error message when you access a friend function with an argument of type nested class in Visual C++ .NET 2003 or in Visual C++ 2005 =

Article ID: 814793

Article Last Modified on 1/10/2007

-

APPLIES TO


 * Microsoft Visual C++ 2005 Express Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition

-





SYMPTOMS
When you use Microsoft Visual C++ .NET 2003 or Microsoft Visual C++ 2005 to access a friend function with an argument of type nested class that is in an enclosing class, you may receive the following error messages:

error C3767: '==' matching function is not accessible could be the friend function at 'path to the code file' : '==' [may be found via argument-dependent lookup]

error C2676: binary '==' : 'A::B' does not define this operator or a conversion to a type acceptable to the predefined operator

When you receive this error, Argument-dependent lookup (which is also known as Koenig lookup) is not working for the argument type as a nested class.



CAUSE
According to the International Organization for Standardization (ISO) C++ standards (ISO/IEC 14882), if an argument type is of class type, the associated classes are the class itself and its direct and indirect base classes. Therefore, associated classes do not include any classes where the class or the struct is nested.



RESOLUTION
In the example code in the &quot;More Information&quot; section of this article, the operator overload == is a friend function: friend bool operator==(B, B){return false;} The friend function is declared in the scope of struct A and outside the scope of struct B. According to ISO C++ standards, the name is not visible in the surrounding scope. Therefore, you receive the error that is listed in the &quot;Symptoms&quot; section of this article.

However, the International Organization for Standardization (ISO) introduced a mechanism to make such operators work and found that Argument-dependent lookup may be used. This mechanism is named &quot;inline friend definitions of operators applying to the class.&quot; Accordingly, the rule is that friend declarations are visible when they are found through Argument-dependent lookup because an argument of the call is associated with a class where the function is a friend of the class.

The example code in the &quot;More Information&quot; section of this article violates this rule. However, you can modify the same example by moving the overload operator for == in the declaration of struct B: struct A {

struct B { friend bool operator==(B, B){return false;} };

};

bool operator!=(A::B b0, A::B b1) {    return !(b0==b1); }



STATUS
This behavior is by design.



MORE INFORMATION
With Argument-dependent (Koenig) lookup, when a function is called, the namespaces where the function parameters reside are taken into account to determine if that function is visible in the current scope.

Argument-dependent lookup examines types of all arguments in a function, and the associated namespaces and classes or structs are collected. The name of the function is then looked up in all the namespaces and classes or structs.

The following code example compiles in Microsoft Visual C++ .NET 2002 because the friend function declaration is exported to the enclosing nonclass scope. In this case, the enclosing nonclass scope is the global scope:
 * 1) include

struct A { struct B           { };   friend bool operator==(B, B){return false;} };

bool operator!=(A::B b0, A::B b1) {        return !(b0==b1); //error C3767: '==' matching function is not accessible could be the friend function [may be found via argument-dependent lookup] }

int main { return 0; } Note You must add the common language runtime support compiler option (/clr:oldSyntax) in Visual C++ 2005 to successfully compile the previous code sample. To add the common language runtime support compiler option in Visual C++ 2005, follow these steps:
 * 1) Click Project, and then click   Properties.

Note  is a placeholder for the name of the project.
 * 1) Expand Configuration Properties, and then click General.
 * 2) Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting in the right pane, click Apply, and then click OK.

For more information about the common language runtime support compiler option, visit the following Microsoft Web site:

/clr (Common Language Runtime Compilation)

http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

To reproduce this behavior, compile the code sample in the &quot;More Information&quot; section of this article by using Visual C++ .NET 2003 or Visual C++ 2005. You receive the error that is described in the &quot;Symptoms&quot; section of this article. This error occurs for the following reasons:
 * Visual C++ .NET 2003 complies with 98 percent of the ISO C++ standards. That is a higher level than by any previous version of Visual C++. Visual C++ .NET 2003 also contains new language support for features such as Koenig lookup.
 * In Visual C++ .NET 2003, no more friend declarations are exported to the nonclass scope. Instead, overloaded friend operators are resolved with the help of Argument-dependent lookup.

Therefore, in Visual C++ .NET 2003, the compiler strongly adheres to the rule that is specified in the &quot;Resolution&quot; section of this article.

