C++ C++;03:是否有一种方法可以使一个类型在每次包含在模板参数中时编译为不同的类型?
我正在努力实现这样的目标:C++ C++;03:是否有一种方法可以使一个类型在每次包含在模板参数中时编译为不同的类型?,c++,templates,hash,types,c++03,C++,Templates,Hash,Types,C++03,我正在努力实现这样的目标: typeof(vector<MyStrangeType>) != typeof(vector<MyStrangeType>) typeof(向量)!=类型(向量) 也就是说,每次将此类型作为模板参数包含时,我都希望它生成不同的类型 我可能实际希望这样做的一个例子是避免在这种情况下出现未定义的行为: class DeviousHashAlg { private: int seed; public DeviousHash
typeof(vector<MyStrangeType>) != typeof(vector<MyStrangeType>)
typeof(向量)!=类型(向量)
也就是说,每次将此类型作为模板参数包含时,我都希望它生成不同的类型
我可能实际希望这样做的一个例子是避免在这种情况下出现未定义的行为:
class DeviousHashAlg {
private:
int seed;
public
DeviousHashAlg() {
seed = rand();
}
template<class TYPE>
size_t operator()(TYPE key) {
return hash<TYPE>()(key) * seed
}
}
unordered_map<SomeKey, SomeValue, DeviousHashAlg> map1;
unordered_map<SomeKey, SomeValue, DeviousHashAlg> map2;
map1 == map2; // Currently undefined
类设备hashalg{
私人:
int种子;
公众的
DeviousHashAlg(){
种子=兰德();
}
模板
大小\u t运算符()(键入键){
返回哈希()(键)*种子
}
}
无序地图1;
无序地图2;
map1==map2;//当前未定义
比较这些映射是未定义的行为,因为其中的值不会哈希到相同的bucked。我想做的是将这个未定义的行为改为编译时错误。这就是为什么我希望DeviousHashAlg
每次包含在像unordered\u map
这样的模板中时都生成一个不同的类型,这样我们就不允许使用=
这可能吗?如果可能的话,我更愿意使用语言支持,尽管我怀疑某些预处理黑魔法可能是唯一的解决方案。您可以使用宏
\uuuuu计数器\uuuu
并按如下方式制作类模板:
template <std::size_t N>
struct DeviousHashAlg
{
/* Your code */
};
#define UNIQUE_DeviousHashAlg DeviousHashAlg<__COUNTER__>
模板
结构DeviousHashAlg
{
/*你的代码*/
};
#定义唯一的_devicehashalgdevicehashalg
然后,为了
unordered_map<SomeKey, SomeValue, UNIQUE_DeviousHashAlg> map1;
unordered_map<SomeKey, SomeValue, UNIQUE_DeviousHashAlg> map2;
无序地图1;
无序地图2;
map1
和map2
将有不同的类型。你确定你正确使用了术语“未定义的行为”吗?如果=
是你唯一担心的-你可以明确告诉编译器将其视为错误:内联bool操作符==(常量和无序映射,常量和无序映射){错误非法!}我相信我是新的C++世界,所以我可能错过了使用它。请您澄清一下您认为我的陈述有什么错误,以及我如何纠正它好吗?DeviousHashAlg
不是一个错误。@Pradhan您是对的,它不符合std::hash
的要求,但是,它不是std::hash
的专门化DeviousHashAlg
是一个全新的哈希算法,如果它真的得到了适当的充实,它将具有一个理想的特性,能够阻止哈希表DOS攻击(我很清楚,在它当前的版本中它没有)。注意:\uu COUNTER\uuuuuu
是一个编译器扩展,而不是由standard@icepack:没错,但至少msvc、gcc和clang支持它。事实上,我本来打算写完全相同的答案,但你比我快了5分钟:)这可能对GBleaney的目的不重要,但我认为\uuuuu COUNTER\uuuuu
每个翻译单元从0开始,因此如果跨翻译单元使用,可能会造成各种破坏(例如,客户端和报头的实现文件会看到报头中的类型不同,意外重复…)