我在理解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;
}我的编译器告诉我,对x和y的引用是不明确的。为什么会这样呢?
发布于 2013-07-22 23:02:39
这里有一个简单的原因,为什么这不能像你预期的那样工作:
namespace bogus {
const int x;
}
namespace heinous {
const int x;
}
using namespace bogus;
using namespace heinous;
const int x = 10;现在,上面的x应该指的是bogus::x、heinous::x还是一个新的全局::x?这将是第三次不使用using语句,这意味着在这里添加using语句将以一种特别微妙的方式改变现有代码的含义。
using语句用于引入用于查找的范围(通常但不一定是名称空间)的内容。这句话
const int x = 10;通常不需要首先进行查找,除非检测到ODR违规。
发布于 2013-07-22 22:56:37
声明/定义中标识符的名称查找与使用中的名称查找的工作方式不同。特别是,它并不关心是否使用语句。原因很简单:如果它是不同的,它将导致各种令人不快的惊喜。请考虑以下内容:
// 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被正确链接到其他文件中的使用。但是,如果名称查找的工作方式不同,一些文件会突然定义sneakattack::foo,而不是::foo,程序将无法链接。
https://stackoverflow.com/questions/17790602
复制相似问题