union
成员可能没有析构函数或构造函数。所以我不能模板化以下类 Foo
靠我自己MyClass
如果MyClass
有一个构造函数:
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_) {}
};
如果我这样做,我会得到这个错误:
member 'MyClass Foo<T>::hash() const
[with T = MyClass]::<anonymous union>::f' with constructor
not allowed in union
为了解决这个问题,我创建了 MyClass
有一个笨拙的构造函数,它首先复制周围的东西:
struct MyClass {
bool a;
double b;
};
MyClass createMyClass(bool a, double b) {
MyClass m;
m.a = a;
m.b = b;
return m;
}
但我想知道是否有比使用这个 createMyClass
更好的方法功能。构造函数会更有效,并且作为关键组件 MyClass
和 Foo<MyClass>
在我的代码中构造了数百万次。
标准::对
我也有点惊讶它可以使用std::pair
在union
:
Foo<std::pair<bool, double> > f2(std::make_pair(true, 3.12));
据我所知,std::pair
( see code ) 有一个构造函数?
最佳答案
编辑:我最初对std::pair
的立场是错误的,它不应该被允许出现在 union 中。对于要成为 union 的有效成员的类,它必须具有符合标准 9.5.1 的普通构造函数。普通构造函数的定义是这样的,来自第 12.1.5 段:
If there is no user-declared constructor for class X, a default constructor is implicitly declared. An implicitly-declared default constructor is an
inline public
member of its class. A constructor is trivial if it is an implicitly-declared default constructor and if:
- its class has no virtual functions and no virtual base classes, and
- all the direct base classes of its class have trivial constructors, and
- for all the nonstatic data members of its class that are of class type (or array thereof), each such class has a trivial constructor
第 20.2.2.2 段声明以下构造函数必须成对可用:
pair(const T1& x, const T2& y);
只要提供此构造函数,就不会隐式声明任何默认构造函数。
有趣的是,我的编译器 (Visual Studio 2008) 似乎给予 std::pair
特殊待遇。如果我从 std::pair
实现中复制代码并将其放在我自己的命名空间 foo 中, union 将不起作用:)
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;
}
您的解决方案是解决此问题的常用方法。我通常在类名前加上 C
(construct 的缩写)以部分模仿普通的构造函数语法,在您的情况下这将变为 CMyClass(a, b)
。
正如 Steve 和 Matthieu 所指出的,您没有使用非常好的哈希函数。首先,并不能真正保证(我认为,如果我错了请纠正我) union 体中的 f
和 s
甚至会部分占用相同的内存空间,其次即使他们在实践中可能会共享第一个 min(sizeof(s), sizeof(f))
字节,这意味着对于 MyClass
你只是部分散列的值(value)。在这种情况下,您将对 bool a
的值进行哈希处理,在这种情况下有两个选项:
- 您的编译器使用
int
作为bool
的内部表示,在这种情况下,您的哈希函数将只返回两个值,一个为真,一个为假。< - 您的编译器使用
char
作为bool
的内部表示。在这种情况下,该值可能会被填充到至少sizeof(int)
,或者用零填充,在这种情况下,您的情况与 1 相同。或者在时使用堆栈上的任何随机数据>MyClass
已分配,这意味着您将获得相同输入的随机哈希值。
如果您需要对 T
的整个值进行散列,我会像 Steve 建议的那样将数据复制到一个临时缓冲区中,然后使用讨论的可变长度散列函数之一 here .
关于c++ - union 成员可能没有构造函数,但是 `std::pair` 可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1888293/