c++ - 构造函数中的部分模板推导

标签 c++ templates constructor c++17

问题:我经常处于这样一种情况,可以从构造函数的参数中推导出某些类型,但不是全部:

template <typename Res, typename Arg>
struct adder {
    adder (Arg a1, Arg a2) : a1 {a1}, a2 {a2} {}
    void compute () { res = a1 + a2; }
    Res result () { return res; }

    Arg a1, a2;
    Res res;
};
如果我正在使用 int参数并想指定 unsigned作为结果类型,我想写一些类似的东西:
auto add = adder<unsigned>(42, -51);
......这不起作用。但是,我不想明确提及int .
候选解决方案:我可以想到两种“让它发挥作用”的方法,首先是与制造商合作:
template <typename Res>
struct wrapper {
    template <typename Arg>
    static auto make_adder (Arg a1, Arg a2) {
      return adder<Res, Arg> (a1, a2);
    }
};

auto add = wrapper<unsigned>::make_adder (42, -51);
其次,确保可以在构造函数中推导出所有类型:
template <typename Res, typename Arg>
struct adder_extra {
    adder_extra (Arg a1, Arg a2, Res r) : a1 {a1}, a2 {a2} {}
    void compute () { res = a1 + a2; }
    Res result () { return res; }

    Arg a1, a2;
    Res res;
};

auto add = adder_extra (42, -51, (unsigned) 0);
问题:有没有首选的方法?这可以用另一种方式更巧妙地解决吗?

最佳答案

你没有提到的一个选项是像标准库那样做,并释放 maker 函数:

template <typename Res, typename Arg>
auto make_adder (Arg a1, Arg a2) {
      return adder<Res, Arg> (a1, a2);
}
函数的模板参数推导允许指定模板参数的一部分。 make_adder<unsigned>(42, -51)是完全有效的,最早可以追溯到 C++98。
这也是一种解决方法,没错。但它是一种流行和惯用的方法。

1 - std::make_unique , std::make_shared , std::make_optional , std::make_any , std::make_tuple , 等等。

关于c++ - 构造函数中的部分模板推导,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66164903/

相关文章:

java - 是否有 Lombok 方法来初始化从其他字段计算的最终字段?

c++ - 使用可变参数模板重载函数模板 : Intel c++ compiler version 18 produces different result from other compilers. intel 错了吗?

c++ - 如何声明自引用模板 typedef

c++ - map::const_iterator 映射类型不是 const

c++ - 成员函数模板是否需要 "inline"

asp.net-mvc - 如何覆盖 @Html.LabelFor 模板?

c++ - 继承构造函数和大括号或等于初始值设定项

c++ - 当其他构造函数存在时,为什么 "ctor() = default"会改变行为?

c++ - 将对象指针复制到动态对象数组中

c++ - 库的析构函数中的 "Incorrect checksum for freed object"