专用模板是命名空间别名实际上是一个别名
Specializing templates in 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 个具有 N 个不同专用化的文件提供 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...
"的各种错误,这不应该发生,因为命名空间可以多次重新打开,如果别名是别名而不是其他东西,那么这也应该适用于它们。
那么,命名空间别名真的是别名,还是用词不当意味着其他东西?还是有其他原因导致我不能以这种方式专业化?如果是这样,还有其他方法(比 #defines 弹幕更好(?
是的,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
}
正确的宏:
// 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;
}
(但这一切都不好(
- 别名一个模板函数,该功能没有参数可更简洁
- 成员模板别名与另一个模板成员
- 如何在C 中为多个类创建一个别名
- 创建一个从一种类型到另一种类型的别名
- 将预定但非初始化的向量设置为另一个别名
- 如何在c中给出一个函数的别名
- 依赖于参数的查找在来自另一个命名空间的别名类型上意外行为
- 如何使用模板别名删除一个不必要的参数
- C++11中一个专用模板的名称别名
- 专用模板是命名空间别名实际上是一个别名
- 从成员函数指针到另一个类型的强制转换,返回严格的别名问题
- 一个命名空间有多个别名
- 是否可以在googleprotobuf中为类型(枚举或消息)定义一个别名
- 为singleton实例调用函数创建一个别名
- 将参数包从一个模板复制到另一个模板,并在内部别名中同时使用结果
- 我可以用别名模板专门化一个类模板吗?
- 能否在c++中向前声明一个命名空间别名?
- 一个空的别名shared_ptr是一个很好的替代无操作删除shared_ptr吗?
- 模板别名为另一个别名
- 如何用可变数量的参数别名一个函数