除了使用“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 是一个变量;可以是::XN::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:由于is 不是问题的一部分,您始终可以将它们声明为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 草案之外,还有其他可能证明这一点的方法吗的主要内容,如果未能解决你的问题,请参考以下文章

static关键字在命名空间范围内没用吗?

C extern 关键词分析

C笔试题之简答题

在 C# CLR 中学习 C++ 之了解 extern

C# 关键字extern用法

为啥“extern”关键字在同一个文件中不起作用?