You may receive a "C3767" 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 (814793)
The information in this article applies to:
- Microsoft Visual C++ 2005 Express Edition
- Microsoft Visual C++ .NET (2003)
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. CAUSEAccording 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. RESOLUTIONIn the example code in the "More Information" 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
"Symptoms" 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 "inline friend definitions of operators applying to the
class." 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 "More Information" 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 INFORMATIONWith 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: #include <iostream>
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:
- Click Project, and then click <ProjectName> Properties.
Note <ProjectName> is a placeholder for the name of the project. - Expand Configuration Properties, and then click General.
- 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: To reproduce this behavior, compile the code sample in the "More
Information" section of this article by using Visual C++ .NET 2003 or Visual C++ 2005. You receive
the error that is described in the "Symptoms" 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 "Resolution" section of this
article. REFERENCES For
additional information about Koenig lookup, click the following article number
to view the article in the Microsoft Knowledge Base: 242190
BUG: Full Koenig Lookup Works Only for Operators
For more information about improvements in Visual
C++ .NET 2003, visit the following Microsoft Developer Network (MSDN) Web site:
Modification Type: | Major | Last Reviewed: | 1/11/2006 |
---|
Keywords: | kbprb kberrmsg kbLangCPP kbCPPonly kbCompiler KB814793 kbAudDeveloper |
---|
|