gpt4 book ai didi

c++ - 使 C++ 初始化程序自动检测 union 成员?

转载 作者:行者123 更新时间:2023-11-30 02:41:47 25 4
gpt4 key购买 nike

好吧,标准仍然说大括号初始化 union 只会初始化第一个成员。我想这会将这个问题更多地放在“如果......不是很好吗?”类别。

一定要这样吗?毕竟,我们现在可以自动检测其他类型。

auto x = 3; // int
auto s = "foo"; // char *
auto w = L"Foo"; // wchar_t *

那么为什么不加入 union 呢?鉴于:

struct init 
{
int t;
union {
long long x;
char *s;
wchar_t *w;
};
};

目前你只能用大括号初始化init::x(使用int),而不是sw

可以扩展自动类型检测,以便根据初始化程序的类型选择初始化的 union 成员:

auto init initial_data [] = {
{ 0, 3 }, // initializes x, brace elision
{ 1, "foo" }, // initializes s
{ 2, L"Foo" } // initializes w
};

(当然,这不应该在当前标准中编译。)

这样可以将所有 initial_data 放在一个初始化列表中。 (我怀疑 auto 关键字必须去别的地方)。

是否有什么原因使它成为一个坏主意(除了“还没有人想到它”或“它太难实现”之外)?目前你必须做一些可怕的事情,比如:

#define RI(X) reinterpret_cast<long long>(X)
const init initial_data[] = {
{ 0, 3 }, // initializes x, brace elision
{ 1, RI("foo") }, // initializes s
{ 2, RI(L"Foo") } // initializes w
};

我不想经历这些扭曲,除了 std::exception 必须用 std::string 初始化(即基于 char),所以我不能只有一个包含所有 wchar_t* 的初始化列表。我真的很喜欢所有这些初始化程序都在同一个地方。

最佳答案

更新

在我的介绍中我提到:

(though A union can have member functions (including constructors and destructors)

我刚刚意识到这使您能够自己编写所需的构造函数!

struct init {
init(long long v) : t(type::longlong), x(v) {}
init(char const* v) : t(type::pcsz), s(v) {}
init(wchar_t const* v) : t(type::pwcsz), w(v) {}

enum class type { longlong, pcsz, pwcsz } t;
union { long long x; char const* s; wchar_t const* w; };
};

现在编译:

init initial_data [] = {
3 , // initializes x, brace elision
"foo" , // initializes s
L"Foo" // initializes w
};

查看 Live On Coliru


Q. Is there something making this a Bad Idea (beyond "nobody's thought of it yet" or "it's too hard to implement")

一般来说,union 通常是个坏主意。很难安全地使用它们。在这方面,它们有点像 C++ 中的“二等”公民(尽管现在 union 体可以有成员函数(包括构造函数和析构函数),但不能有虚函数)。

让编译器选择“the”插槽来接收初始化程序可能很快就会遇到歧义。

通过大括号初始化,他们可以添加一些限制(没有缩小/扩大转换),就像 C++11 中已有的初始化列表一样。

但这都是幻想。简而言之:这不是语言功能


boost::variant 有这种行为。

注释

  • which() 成员基本上是您的类型鉴别器 (t)
  • 您可以优化大小:BOOST_VARIANT_MINIMIZE_SIZE
  • 如果您想从字面量赋值,您应该使 char/wchar_t 指针const*!

Live On Coliru

#define BOOST_VARIANT_MINIMIZE_SIZE
#include <boost/variant.hpp>

using init = boost::variant<long long, char const*, wchar_t const*>;

#include <iostream>

int main() {
init initial_data [] = {
3 , // initializes x, brace elision
"foo" , // initializes s
L"Foo" // initializes w
};

for(auto& v : initial_data)
std::cout << v.which() << "\t" << v << "\n";
}

输出:

0   3
1 foo
2 0x401f14

关于c++ - 使 C++ 初始化程序自动检测 union 成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27708129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com