C++:保留聚合初始化的模板结构体类型转换实现方案问询
保留聚合初始化特性的模板结构体类型转换方案
现有代码基础
我们有一个支持指定初始化器的模板结构体:
template <typename T> struct ag_init { T a, b; };
使用指定初始化器的方式非常便捷:
ag_init a1{.a = 1, .b = 2};
同时定义了支持隐式转换的自定义类型:
struct float_like { float i; }; struct double_like { double d; double_like() = default; double_like(double) {} double_like(float_like) {} };
需求目标
希望ag_init能像glm::fvec3隐式转换为glm::dvec3那样,支持不同模板参数间的类型转换,具体需要实现:
ag_init<float_like> a1{.a = float_like{1}, .b = float_like{2}}; ag_init<double_like> a2{.a = double_like{1}}; a2 = a1; // 支持赋值转换 ag_init<double_like> a4{a1}; // 支持花括号初始化转换
当前面临的问题
- 赋值转换已经通过重载赋值运算符实现,但如果给
ag_init添加转换构造函数,会导致结构体失去默认构造能力,同时不再是聚合类型,无法再使用指定初始化器。 - 借助辅助结构体的实现方案存在拷贝冗余、语法繁琐的缺点。
- 尝试添加转换运算符仅能部分解决问题:
这个方案支持圆括号形式的转换构造,但无法支持花括号初始化:template <typename U> requires (std::convertible_to<T, U> && !std::is_same_v<T, U>) operator ag_init<U>() const { return {.a = static_cast<U>(a), .b = static_cast<U>(b)}; }ag_init<double_like> a4{a1}; // 编译失败
寻求最优方案
需要找到一种既能保留ag_init的聚合类型特性(即支持指定初始化器),又能实现不同模板参数的ag_init之间隐式/显式类型转换的方案。
内容的提问来源于stack exchange,提问作者Fantastic Mr Fox
相关产品推荐
相关产品推荐

