使C++初始值设定项自动检测工会成员
Make a C++ initializer automatically detect union member?
好的,标准仍然说大括号初始化联合只初始化第一个成员。 我想这把这个问题更多地放在"如果......不是很好吗?"类别中。
一定要这样吗?毕竟,我们现在有其他类型的自动类型检测。
auto x = 3; // int
auto s = "foo"; // char *
auto w = L"Foo"; // wchar_t *
那么为什么不成立工会呢?鉴于:
struct init
{
int t;
union {
long long x;
char *s;
wchar_t *w;
};
};
目前您只能用大括号初始化init::x
(带有int
),而不能s
或w
。
可以扩展自动类型检测,以便根据初始值设定项的类型选择已初始化的联合成员:
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::string
初始化std::exception
(即基于 char
),所以我不能只有一个包含所有wchar_t*
的初始值设定项列表。 我真的很想把所有这些初始值设定项都放在同一个地方。
更新
在我的介绍中,我提到:
(尽管联合可以具有成员函数(包括构造函数和析构函数)
我刚刚意识到这使您能够自己编写所需的构造函数!
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
};
在科里鲁现场观看
问。是否有什么东西使这是一个坏主意(除了"还没有人想到它"或"它太难实现")
一般来说,union
通常是一个坏主意。很难安全地使用它们。在这方面,他们在C++有点"二等"公民(尽管现在联盟可以有成员函数(包括构造函数和析构函数),但不能有虚函数)。
让编译器选择"the"槽来接收初始值设定项可能很快就会遇到歧义。
通过大括号初始化,他们可以添加一些限制(没有缩小/扩大转换),就像 C++11 中的初始值设定项列表一样。
但这都是幻想。简而言之:这不是语言功能。
boost::variant
有这种行为。
笔记
which()
成员基本上是你的类型鉴别器(t
)- 您可以针对大小进行优化:
BOOST_VARIANT_MINIMIZE_SIZE
如果要 - 从文字分配,则应
const*
字符/wchar_t指针!
住在科里鲁
#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
- 无法获得 std::from_chars 自动检测基础
- QImage:加载图像时自动检测格式
- 如何让Visual Studio自动检测子文件夹中的.cpp文件?
- 带有常量后缀的自动解析成员函数
- GCC - 如何自动检测每个基本模块
- 如果派生类仅包含自动变量成员,是否有必要具有虚拟驱动器
- 自动检测C++14 "return should use std::move"情况
- SFINAE:检测成员变量的存在在 g++ 上不起作用
- c++Windows自动检测代理设置
- 是否有IDE或VIM插件或可以在编写代码中自动完成成员功能的任何内容
- 函数有没有办法自动检测其参数的数据类型?(请不要建议函数重载)
- 类中的自动调用成员函数
- 自动检测源以进行自动制作
- 使C++初始值设定项自动检测工会成员
- 如何使用 C/C++自动检测 snmp 设备
- C++ 自动使用成员初始值设定项语法和已删除的复制构造函数
- 使用SFINAE检测成员函数
- 用c++实现函数对象的自动检测类型
- 使用void_t检测成员
- C/C++中操作系统的自动检测