我正在努力为我一直在努力的一系列类型提供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
当然,如果我被迫,我会坚持这个策略但我之前想探索其他一些选择。特别是,我可以使用 namespace alias 来专注于正确的位置:
#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...
”的各种错误,这应该是'因为命名空间可以多次重新打开,并且如果别名是别名而不是别的,那么这也应该适用于它们。
那么,命名空间别名真的是别名,还是用词不当意味着什么呢?还是有其他原因我不能这样专门化?如果是这样,任何其他方法(优于#defines的拦截)?
答案 0 :(得分:1)
是的,namespace
别名实际上是别名。发生错误是因为您将std_specialize
声明为std
或std::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
}
答案 1 :(得分:0)
正确的宏:
// 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;
}
(但所有这一切都不好)