2012-03-26 57 views
3

我有以下代码,使用g ++ 4.4.6可以正常工作,但无法使用Visual Studio 2008进行编译。它似乎与参数依赖查找有关,所以我认为g ++是正确的。using指令如何影响C++中的函数参数?

// 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:\工作\ testproject \ testproject \ testclass.cpp (6):error C2065:'foo':未声明的标识符 1> c:\ work \ testproject \ testproject \ testclass.cpp(6):error C2065:'input':未声明的标识符 1> c:\ work \ testproject \ testproject \ testclass.cpp(6):error C2448:'test :: usesFoo :: memberFunc':函数式初始化器似乎是函数定义

我意识到将命名空间直接放在cpp文件中的成员函数上,或者“using namespace test”会解决这个问题,我更加好奇这个标准所说的是什么。

+1

我没有看到任何理由期望您的代码编译; foo没有在usesFoo中定义。这很有趣,它用g ++编译。 – 2012-03-26 20:57:36

+2

'memberFunc'不是静态的,'foo'不合格。 *参数*依赖查找意味着*函数*的名称在参数的名称空间中查找,而不是相反。 – 2012-03-26 20:57:52

+0

+1 – 2012-03-26 21:06:49

回答

1

该代码是正确的,但它与查询依赖查找无关。另外,使用声明仅影响usesFoo而不是foo的查找:一旦您发出了类成员的名称,就会在该类的上下文中查找其他名称。由于foo是test :: usesFoo的成员。如果没有使用指令你需要这样定义的成员函数:

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

此相关的条款是3.4.1不合格的名称查找[basic.lookup.unqual]第6款:

函数声明符id后面的函数定义中使用的名称是名称空间N的成员(其中,仅用于说明的目的,N代表全局作用域)应在其用于在其使用的块或其封闭块(6.3)之一中,或者应在其用于名称空间N之前进行声明,或者如果N是嵌套名称空间,则应在其使用之前声明为其中一个N包含名称空间。

仅当函数被调用时才会进入图片,而不是在定义函数时进入图片。这些东西根本就没有任何关系。