Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the using directive affect function arguments in C++?

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.

like image 356
MikeT Avatar asked May 01 '26 02:05

MikeT


1 Answers

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.

like image 154
Dietmar Kühl Avatar answered May 02 '26 17:05

Dietmar Kühl