Как директива using влияет на аргументы функции в C ++? - PullRequest
3 голосов
/ 27 марта 2012

У меня есть следующий код, который отлично работает с использованием g ++ 4.4.6, но не компилируется с использованием Visual Studio 2008. Кажется, он связан с Argument Dependent Lookup, поэтому я считаю, что g ++ верен.

// 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;
}

Ошибка при компиляции в Visual Studio:

1> Компиляция ...
1> testClass.cpp 1> c: \ work \ testproject \ testproject \ testclass.cpp (6): ошибка C2065: 'foo': необъявленный идентификатор 1> c: \ work \ testproject \ testproject \ testclass.cpp (6): ошибка C2065: «ввод»: необъявленный идентификатор 1> c: \ work \ testproject \ testproject \ testclass.cpp (6): ошибка C2448: 'test :: usedFoo :: memberFunc': инициализатор стиля функции выглядит как определение функции

Я понимаю, что решение проблемы может заключаться в том, чтобы либо поместить пространство имен непосредственно в функцию-член в файле cpp, либо "использовать тест пространства имен", - мне более любопытно, что именно говорит стандарт в этом случае.

1 Ответ

1 голос
/ 27 марта 2012

Код правильный, но он не имеет ничего общего с зависимым от аргумента поиском.Кроме того, объявление using влияет только на поиск usesFoo, а не foo: как только вы произнесете имя члена класса, другие имена ищутся в контексте этого класса.* * * * * * * * foo является членом теста test :: usedFoo`.Без директивы using вам нужно было бы определить функцию-член следующим образом:

void test::usesFoo::memberFunction(foo& input) {
    (void)input;
}

Соответствующим условием для этого является пункт 3.4.1 Поиск безусловного имени [basic.lookup.unqual] параграф 6:

Имя, используемое в определении функции после идентификатора объявления функции, являющегося членом пространства имен N (где только для целей представления N может представлять глобальную область)перед его использованием в блоке, в котором он используется, или в одном из входящих в него блоков (6.3), или, должны быть объявлены перед его использованием в пространстве имен N, или, если N является вложенным пространством имен, должны быть объявлены перед его использованием в одном изПространства имен, вмещающие N.

Поиск, зависящий от аргумента, входит в изображение только при вызове функции, а не при ее определении.Эти вещи не имеют ничего общего друг с другом.

...