除了使用“extern”关键字:n3290 草案之外,还有其他可能证明这一点的方法吗
Posted
技术标签:
【中文标题】除了使用“extern”关键字:n3290 草案之外,还有其他可能证明这一点的方法吗【英文标题】:Is there any other possiblitly to prove this point other than using 'extern' keyword :n3290 draft 【发布时间】:2011-10-13 03:19:53 【问题描述】:ISO 草案 N3290 中的一点: 不合格名称查找:第 3.4.1 节,第 14 段:
如果命名空间的变量成员在其范围之外定义 命名空间,然后是出现在成员定义中的任何名称 (在 declarator-id 之后)被查找为成员的定义 发生在其命名空间中。
例如:
namespace N
int i = 4;
extern int j;
int i = 2;
int N::j = i; // N::j == 4
除了使用'extern'关键字之外,还有其他方法可以证明这一点
你能举一些其他的例子吗...除了extern
【问题讨论】:
【参考方案1】:// header.h
struct X void bar () ;
namespace N
struct X void bar () ;
void foo(X *p = new X);
// implementation.cpp
#include"header.h"
N::foo(X* p) p->bar(); // N::X::bar() called
这个例子没有使用extern
。 (虽然是暗示的)。
【讨论】:
您认为N::foo
是“命名空间的变量成员”?
@6502,而不是N::foo
;但适用于N::foo
中的所有变量数据成员:)。 OP 已经给出了外部变量的例子。
那么你的答案不相关:-1
我还是看不到“命名空间的变量成员”,你知道吗?
@6502,你应该看到foo(X* p = new X)
;其中X
是一个变量;可以是::X
或N::X
。【参考方案2】:
另一个例子是关于类中的静态成员的定义。
// header
namespace N
const int i = 4;
class A
public:
static int m_i;
;
// source file
int i = 2;
int N::A::m_i = i; // N::A::m_i == 4
int main(int argc, char* argv[])
cout << N::A::m_i << endl;
return 0;
【讨论】:
如果namespace N
包含在多个 .cpp 文件中,这会导致链接器错误。你必须使 extern int i;
.
要挑剔,是的。但它已经在命名空间范围内定义,就像在 OP 的代码中一样。所以我认为这对于我们正在讨论的主题来说并不重要。【参考方案3】:
另一个不使用extern
关键字的例子:
//demo.cpp
int i = 100;
namespace N
int i = 200;
struct A
static int m;
;
int N::A::m = i; //i is 100 or 200?
int main()
cout << N::A::m << endl; //what will it print?
输出:
200
在线演示:http://www.ideone.com/pRVAb
【讨论】:
如果namespace N
头文件包含在多个 .cpp 文件中,您的两个示例都会给出链接器错误。所以你最终必须为extern
使用int i;
关键字:)
@iammilind:我在评论中添加了demo.cpp
,以消除链接器错误的可能性。
@iammilind:由于i
s 不是问题的一部分,您始终可以将它们声明为const int i = ...;
,这样就可以避免这个问题。【参考方案4】:
这段代码没有使用extern
,但它或多或少地证明了这一点。请注意,它没有在命名空间之外定义 variable,而是在命名空间之外定义 function。
//demo.cpp
int i = 100;
namespace N
int i = 200;
struct X;
void f(const X&);
void N::f(const X&)
cout << i << endl; //what will it print?
int main()
N::X x;
f(x); //use argument-dependent lookup (ADL) to find the function!
输出:
200
在线演示:http://www.ideone.com/KCqUV
我添加了 ADL 让它更有趣!
【讨论】:
你发了两次。起初我对公然抄袭某人的行为感到震惊,然后我觉得自己很傻。 @GMan:这是一个不同的答案。这不是我其他答案的重复。 那么你应该把它们结合起来。以上是关于除了使用“extern”关键字:n3290 草案之外,还有其他可能证明这一点的方法吗的主要内容,如果未能解决你的问题,请参考以下文章