I have the following code that works fine using g++ 4.4.6, but fails to compile using Visual Studio 2008. It seems related to Argument Dependent Lookup, so I think g++ is correct.
// testClass.hpp
namespace test {
class foo {
public:
foo(){}
};
class usesFoo {
public:
usesFoo() {}
void memberFunc(foo &input);
};
}
// testClass.cpp
#include "testClass.hpp"
using test::usesFoo;
void usesFoo::memberFunc(foo &input) {
(void) input;
}
The error I get when compiling in Visual Studio is,
1>Compiling...
1>testClass.cpp
1>c:\work\testproject\testproject\testclass.cpp(6) : error C2065: 'foo' : undeclared identifier
1>c:\work\testproject\testproject\testclass.cpp(6) : error C2065: 'input' : undeclared identifier
1>c:\work\testproject\testproject\testclass.cpp(6) : error C2448: 'test::usesFoo::memberFunc' : function-style initializer appears to be a function definition
I realize that either putting the namespace directly on the member function in the cpp file, or "using namespace test" will fix the problem, I'm more curious on what exactly the standard says in this case.
The code is correct but it has nothing to do with argument dependent look-up. Also, the using declaration only affects finding of usesFoo and not foo: once you have uttered the name of a class member, other names are looked up in the context of this class. Since foo is a member of test::usesFoo` it found. Without the using directive you'd need to define the member function like this:
void test::usesFoo::memberFunction(foo& input) {
(void)input;
}
The relevant clause for this is 3.4.1 Unqualified Name Look-up [basic.lookup.unqual] paragraph 6:
A name used in the definition of a function following the function’s declarator-id that is a member of namespace N (where, only for the purpose of exposition, N could represent the global scope) shall be declared before its use in the block in which it is used or in one of its enclosing blocks (6.3) or, shall be declared before its use in namespace N or, if N is a nested namespace, shall be declared before its use in one of N’s enclosing namespaces.
Argument dependent lookup only enters the picture when a function is called, not when it is defined. These things have nothing to do with each other at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With