4

I am having trouble understanding c++ namespaces. Consider the following example:

//distr.h

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

Now if I define my variables like the cpp below everything compiles fine

//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;
}

But if I try to simply bring in the bogus namespace and use instead

//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;
}

My compiler tells me that the reference to x and y is ambiguous. Why is that?

4

2 回答 2

6

有一个简单的原因为什么这不能像您预期的那样合理地工作:

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

using namespace bogus;
using namespace heinous;

const int x = 10;

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

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

const int x = 10;

通常不需要首先进行查找,除非检测到 ODR 违规。

于 2013-07-22T15:02:39.253 回答
1

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

// 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 中的使用。但是如果名称查找的工作方式不同, somefile 会突然定义sneakattack::foo, not ::foo,并且程序将无法链接。

于 2013-07-22T14:56:36.703 回答