Fra*_*ank 5 c++ constructor pod unions std-pair
union成员可能没有析构函数或构造函数.所以如果有一个构造函数Foo,我不能自己模板下面的类:MyClassMyClass
template<class T>
struct Foo {
T val;
Foo(T val_) : val(val_) {}
size_t hash() const {
union {T f; size_t s;} u = { val };
return u.s;
}
};
struct MyClass {
bool a;
double b;
MyClass(bool a_, double b_) : a(a_), b(b_) {}
};
Run Code Online (Sandbox Code Playgroud)
如果我这样做,我得到这个错误:
member 'MyClass Foo<T>::hash() const
[with T = MyClass]::<anonymous union>::f' with constructor
not allowed in union
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我创建MyClass了一个笨拙的构造函数,它首先复制了这个东西:
struct MyClass {
bool a;
double b;
};
MyClass createMyClass(bool a, double b) {
MyClass m;
m.a = a;
m.b = b;
return m;
}
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有比使用此createMyClass功能更好的方法.构造函数会更高效,并且作为一个关键组件,MyClass并且Foo<MyClass>在我的代码中构建了数百万次.
我也有点惊讶,这是可以使用std::pair的union:
Foo<std::pair<bool, double> > f2(std::make_pair(true, 3.12));
Run Code Online (Sandbox Code Playgroud)
据我所知,std::pair(见代码)有一个构造函数?
And*_*nck 10
编辑: 我原来的立场std::pair是错误的,不应该允许在工会中.要使类成为union的有效成员,它必须具有根据标准9.5.1的简单构造函数.从第12.1.5节开始,这是一个简单的构造函数的定义:
如果类X没有用户声明的构造函数,则隐式声明默认构造函数.一个隐式声明的默认构造函数是
inline public其类的成员.构造函数是微不足道的 ,如果它是一个隐式声明的默认构造函数,如果:
- 它的类没有虚函数,也没有虚基类
- 它的所有直接基类都有琐碎的构造函数
- 对于类类的所有非静态数据成员(或其数组),每个这样的类都有一个简单的构造函数
第20.2.2.2段规定以下构造函数必须成对使用:
pair(const T1& x, const T2& y);
Run Code Online (Sandbox Code Playgroud)
一旦提供了这个构造函数,就不会隐式声明默认构造函数.
这里有趣的是我的编译器(Visual Studio 2008)似乎给予std::pair特殊处理.如果我从std::pair实现中复制代码并将其放在我自己的命名空间foo中,那么联合会不起作用:)
namespace foo {
template<class _Ty1, class _Ty2> struct pair {
typedef _Ty1 first_type;
typedef _Ty2 second_type;
pair() : first(_Ty1()), second(_Ty2()) {
}
}
}
//This doesn't work in VC2008
union Baz {
foo::pair<bool, double> a;
int b;
}
//This works in VC2008
union Buz {
std::pair<bool, double> a;
int b;
}
Run Code Online (Sandbox Code Playgroud)
您的解决方案是解决此问题的常用方法.我通常在类名前加上一个C(构造的简称)来部分地模仿普通的构造函数语法,这在你的情况下会变成CMyClass(a, b).
正如Steve和Matthieu指出的那样,你并没有使用非常好的哈希函数.首先,没有真正的保证(我认为,如果我错了请纠正我),f并且s在联合中甚至会部分占用相同的内存空间,其次即使它们在实践中可能会共享第一个min(sizeof(s), sizeof(f))字节,这意味着MyClass你只是对值的一部分进行哈希处理.在这种情况下,您将哈希值的值bool a,在这种情况下有两个选项:
int内部表示形式,bool在这种情况下,您的哈希函数将只返回两个值,一个用于true,一个用于false.char用作内部表示bool.在这种情况下,该值可能至少填充sizeof(int)为零,在这种情况下,您具有与1.相同的情况,或者在MyClass分配时堆栈上的任何随机数据,这意味着您获得相同输入的随机哈希值.如果您需要按整个值散列,T我会将数据复制到像Steve建议的临时缓冲区中,然后使用此处讨论的可变长度散列函数之一.
| 归档时间: |
|
| 查看次数: |
8728 次 |
| 最近记录: |