繁体   English   中英

使用命名空间不适用于定义?

[英]using namespace does not work for definitions?

我无法理解c ++名称空间。 请考虑以下示例:

//distr.h

namespace bogus{
    extern const int x;
    extern const int y;
    double made_up_distr(unsigned param);
}

现在如果我将变量定义为下面的cpp,那么编译就好了

//distr.cpp

#include "distr.h"
#include <cmath>

const int bogus::x = 10;   
const int bogus::y = 100;

double bogus::made_up_distr(unsigned param){
    auto pdf = (exp(param) / bogus::x) + bogus::y;
    return pdf;
}

但是,如果我试图简单地引入bogus名称空间并使用

//broken distr.cpp

#include "distr.h"
#include <cmath>

using namespace bogus;

const int x = 10;
const int y = 100;

double made_up_distr(unsigned param){
    auto pdf = (exp(param) / x) + y;
    return pdf;
}

我的编译器告诉我,对xy的引用是不明确的。 这是为什么?

有一个简单的原因,为什么这不能按预期的方式运作:

namespace bogus {
    const int x;
}
namespace heinous {
    const int x;
}

using namespace bogus;
using namespace heinous;

const int x = 10;

现在,上面的x应该引用bogus::xheinous::x还是新的global ::x 它将是没有using语句的第三个,这意味着添加using语句将以一种特别微妙的方式改变现有代码的含义。

using语句用于引入范围的内容(通常但不一定是命名空间)以供查找 该声明

const int x = 10;

除了检测ODR违规外,通常不需要首先查找。

声明/定义中的标识符的名称查找与使用中的名称查找的工作方式不同。 特别是,它不关心使用语句。 这有一个非常简单的原因:如果它不同,它将导致各种令人讨厌的惊喜。 考虑一下:

// sneakattack.h
namespace sneakattack { void foo(); }
using namespace sneakattack;

// somefile.cpp
#include "sneakattack.h"
void foo() { std::cout << "Hello\n"; }

// otherfile.cpp
void foo();
int main() { foo(); }

这个程序目前有效:声明sneakattack::foo被忽略,定义::foo正确链接到otherfile中的用法。 但是如果名称查找工作方式不同, sneakattack::foo会突然定义sneakattack::foo ,而不是::foo ,程序将无法链接。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM