繁体   English   中英

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

[英]Specializing templates in namespaces - is namespace alias really an alias?

我正在尝试为我一直在研究的类型系列提供hash<> 到目前为止很好,专业化本身很容易提供,我已经为numeric_limits<>做了类似的事情。 但我面临的问题是如何以可移植到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

当然,一种选择是使用#defines来访问,打开和关闭适当的命名空间,或者提供N个不同专业的文件,并有条件地#include正确的名称,但这很麻烦:

#if defined(some_c++11_condition)
  #include "c++11-specialization.h"
#elif defined(some_c++03_condition)
  #include "c++03-specialization.h"
#elif (some_other_condition)
  #oh_dear_who_knows_what_this_include_will_be_like
#else_ad_nauseam
#endif

当然, 如果我被迫 ,我会坚持这个策略但我之前想探索其他一些选择。 特别是,我虽然可以使用命名空间别名专门在正确的位置:

#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>...;
}

不幸的是,这在我尝试过的3个编译器(MSVC 2008,GCC 4.7,Clang 3.0)中的任何一个都不起作用,在重新打开命名空间的行中declaration of namespace conflicts with...关于“ declaration of namespace conflicts with... ”的各种错误,这应该是'因为命名空间可以多次重新打开,并且如果别名是别名而不是别的,那么这也应该适用于它们。

那么,命名空间别名真的是别名,还是用词不当意味着什么呢? 还是有其他原因我不能这样专门化? 如果是这样,任何其他方法(优于#defines的拦截)?

是的, namespace别名实际上是别名。 发生错误的原因是您将std_specialize声明为stdstd::tr1的别名,然后尝试声明具有相同名称的namespace 如果是合法的,该声明后,你会std_specialize参考, std (或std::tr1 )或包含您的新的命名空间hash专业化?

你可能想做的是

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

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

#if __cplusplus < 201103L
}
#endif
}

适当的宏:

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

(但所有这一切都不好)

暂无
暂无

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

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