嵌套命名空间与VS 2012的混淆
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌套命名空间与VS 2012的混淆相关的知识,希望对你有一定的参考价值。
我在VS 2012中遇到了一个非常简单的代码问题。我在centOS 7,Debian 8,9,Fedora 25,26,27,28和Ubuntu 14.04,16.04,18.04上测试了这个代码,最新的GCC和Clang编译器都在官方套餐,以及VS 2013,VS 2015,VS 2017.它的工作原理。
以下是有罪代码的最低版本:
file0.h
namespace B {
enum bar {
HELLO,
WORLD
};
}
file1.h
namespace A {
namespace B {
// Some stuff
}
}
file2.h
#include "file0.h"
namespace A {
namespace C {
template<::B::bar = ::B::HELLO> class foo {
// Some stuff
};
}
}
main.cpp
#include <iostream>
#include "file0.h"
#include "file1.h"
#include "file2.h"
int main() {
::A::C::foo<> myFoo;
// Some stuff
}
此代码导致VS 2012上的以下编译错误:
错误C2039:'bar':不是'A :: B'的成员
由于我们在file2.h中的命名空间::A::C
(因此在命名空间::A
中)并且要求命名空间::B
,似乎VS 2012在::
之前忽略B
并首先在当前命名空间::A
中搜索。由于它没有在bar
中找到::A::B
,它只会抛出错误而不是在更高级别的范围内搜索。
鉴于Stack Overflow上的following answer,VS 2012中的命名空间解析似乎存在错误。
我的问题是:
有没有办法解决这个问题而不改变名称空间的名称(对我来说,保持B在:: B和:: A :: B中非常重要)?就像使用其他语法来使用命名空间或使用别名命名空间一样?
注意:编辑了错误再现的代码(它实际上涉及第三个文件file0.h与我的原始帖子相比。我的错误)。
我无法在视觉2013和2008上重现这个错误。它似乎是2010年和2012年的一个特定问题。
也许在命名空间声明之外尝试一个typedef:
namespace B {
enum bar {
HELLO,
WORLD
};
}
typedef ::B::bar my_type;
namespace A {
namespace B {
template<my_type= ::B::WORLD> class foo {
};
}
}
int main(int argc, char* argv[])
{
A::B::foo<> myFoo;
}
以上是关于嵌套命名空间与VS 2012的混淆的主要内容,如果未能解决你的问题,请参考以下文章
使用命名空间的区别(std:: vs ::std::)[重复]
在 .NET 中创建 C++ ATL COM 嵌套命名空间,如 System 命名空间