You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:33:13