C++ 专门化命名空间中的模板-命名空间别名真的是别名吗?

C++ 专门化命名空间中的模板-命名空间别名真的是别名吗?,c++,namespaces,std,template-specialization,C++,Namespaces,Std,Template Specialization,我试图为我一直在研究的一系列类型提供一个散列专门化。到目前为止很好,专门化本身很容易提供,我已经为数值限制做了类似的事情。但我面临的问题是如何以可移植到C++11和-pre-11(C++03或其他)的方式提供专门化 当然,我遇到的问题是,hash可以在几个名称空间中的一个中定义,我被迫在同一个名称空间中提供专门化 // in c++11 namespace std { struct hash<>...; } // in c++03 this is one possibility na

我试图为我一直在研究的一系列类型提供一个
散列
专门化。到目前为止很好,专门化本身很容易提供,我已经为
数值限制做了类似的事情。但我面临的问题是如何以可移植到C++11和-pre-11(C++03或其他)的方式提供专门化

当然,我遇到的问题是,
hash
可以在几个名称空间中的一个中定义,我被迫在同一个名称空间中提供专门化

// in c++11
namespace std { struct hash<>...; }
// in c++03 this is one possibility
namespace std { namespace tr1 { struct hash<>...; } }

// my library's specialization
namespace ????_open {
struct hash<mytype>...;
????_close
当然,如果我迫不得已,我会坚持这个策略,但之前我想探索一些其他的选择。特别是,我认为我可以使用专门从事正确的领域:

#if defined(some_c++11_condition)
  namespace std_specialize = std;
#elif defined(some_c++03_condition)
  namespace std_specialize = std::tr1;
#...
#endif

...

namespace std_specialize {
struct hash<mytype>...;
}
#如果已定义(某些c++11_条件)
名称空间std_specialize=std;
#定义的elif(某些c++03条件)
名称空间std_specialize=std::tr1;
#...
#恩迪夫
...
名称空间std_专门化{
结构哈希。。。;
}
不幸的是,这在我尝试过的3个编译器(MSVC 2008、GCC 4.7、Clang 3.0)中都不起作用,在重新打开名称空间的行中出现了关于“
声明名称空间与…
”的各种错误,这不应该发生,因为名称空间可以多次重新打开,如果一个别名是一个别名而不是别的什么,那么这也应该适用于他们


那么,名称空间别名真的是一个别名,还是一个用词不当意味着什么?还是有其他原因使我不能这样专攻?如果是这样的话,还有其他方法(比大量的#defines更好)

是的,
名称空间
别名实际上就是别名。发生此错误的原因是,您正在将
std\u specialize
声明为
std
std::tr1
的别名,然后尝试使用相同的名称声明
命名空间。如果它是合法的,在该声明之后,
std_specialize
将指什么,
std
(或
std::tr1
)或包含您的
散列
专门化的新名称空间

你可能想做的是

namespace std {
#if __cplusplus < 201103L
namespace tr1 {
#endif

template<>
struct hash<my_type> { ... };

#if __cplusplus < 201103L
}
#endif
}
名称空间std{
#如果uu cplusplus<201103L
名称空间tr1{
#恩迪夫
模板
结构哈希{…};
#如果uu cplusplus<201103L
}
#恩迪夫
}
正确的宏:

// Defined before
// #define NOEXCEPT noexcept

#include <iostream>

#if TR1_CONDITION
// tr1
    #define HASH_NAMESPACE std::tr1
    #define HASH_NAMESPACE_BEGIN namespace std { namespace tr1 {
    #define HASH_NAMESPACE_END }}
#else
// std
    #define HASH_NAMESPACE std
    #define HASH_NAMESPACE_BEGIN namespace std {
    #define HASH_NAMESPACE_END }
#endif

namespace X {
    struct Class {};
}

HASH_NAMESPACE_BEGIN
    template<>
    struct hash<X::Class>  {
        size_t operator()(const X::Class&) const NOEXCEPT { return 123; }
    };
HASH_NAMESPACE_END

int main() {
    HASH_NAMESPACE::hash<X::Class> h;
    std::cout << h(X::Class()) << std::endl;
    return 0;
}
//以前定义过
//#定义NOEXCEPT NOEXCEPT
#包括
#如果TR1_条件
//tr1
#定义哈希_命名空间std::tr1
#定义HASH_NAMESPACE_BEGIN NAMESPACE std{NAMESPACE tr1{
#定义HASH_名称空间_END}
#否则
//性病
#定义HASH_名称空间std
#定义哈希\名称空间\开始名称空间标准{
#定义散列\名称空间\结束}
#恩迪夫
名称空间X{
结构类{};
}
哈希\u名称空间\u开始
模板
结构散列{
size_t操作符()(const X::Class&)const NOEXCEPT{return 123;}
};
散列\u名称空间\u结束
int main(){
HASH_名称空间::HASH h;

std::cout是
noexcept
有效(即忽略)对于C++03,还是它必须被定义掉?@LuisMachuca不是吗?它真的试图声明一个新的名称空间吗?名称空间
std_specialize
已经存在,作为另一个名称空间的别名,因此声明应该重新打开现有的名称空间。这种情况在标准中没有考虑,是解析问题还是其他问题?@Luis I意识到这正是您希望它的意思,但它实际上并不是这样做的:)。在这种情况下,您正试图声明一个新的命名空间。我不知道不允许您的解释的技术原因是什么。
// Defined before
// #define NOEXCEPT noexcept

#include <iostream>

#if TR1_CONDITION
// tr1
    #define HASH_NAMESPACE std::tr1
    #define HASH_NAMESPACE_BEGIN namespace std { namespace tr1 {
    #define HASH_NAMESPACE_END }}
#else
// std
    #define HASH_NAMESPACE std
    #define HASH_NAMESPACE_BEGIN namespace std {
    #define HASH_NAMESPACE_END }
#endif

namespace X {
    struct Class {};
}

HASH_NAMESPACE_BEGIN
    template<>
    struct hash<X::Class>  {
        size_t operator()(const X::Class&) const NOEXCEPT { return 123; }
    };
HASH_NAMESPACE_END

int main() {
    HASH_NAMESPACE::hash<X::Class> h;
    std::cout << h(X::Class()) << std::endl;
    return 0;
}