使用可变模板进行统一初始化
uniform initialization with variadic templates
本文关键字:初始化 更新时间:2023-10-16
我有一个POD ChParam
,它是可变模板函数set
中的一个参数。我想传递给函数参数(构造函数参数)在花括号p.set({ Param::D, 1000.f }, { Param::p, 2000.f })
。并且认为将隐式调用构造函数并创建ChParam
对象。但这是不可能的,我应该显式地创建一个对象a.set(ChParam{ Param::D, 1000.f }, ChParam{ Param::p, 2000.f });
是否有可能使用p.set({ Param::D, 1000.f }, { Param::p, 2000.f })
的变体?
#include <iostream>
using namespace std;
using Float = float;
enum class Param : size_t
{
D = 0,
p
};
struct ChParam
{
Param tag_;
Float value_;
};
class PipeCalcParams
{
private:
Float D_, p_;
public:
PipeCalcParams() : D_(0), p_(0) {}
PipeCalcParams& set_D(Float D) { D_ = D; return *this; }
PipeCalcParams& set_p(Float p) { p_ = p; return *this; }
template <typename... Args>
PipeCalcParams& set(const ChParam& p, Args&&... args) {
set(p);
return set(args...);
}
PipeCalcParams& set(const ChParam& p)
{
switch (p.tag_)
{
case Param::D:
set_D(p.value_);
break;
case Param::p:
set_p(p.value_);
break;
}
return *this;
}
};
int main() {
PipeCalcParams a;
a.set(ChParam{ Param::D, 1000.f }, ChParam{ Param::p, 2000.f });//OK
PipeCalcParams p;
p.set({ Param::D, 1000.f }, { Param::p, 2000.f });//error: no matching function for call to 'PipeCalcParams::set(<brace-enclosed initializer list>, <brace-enclosed initializer list>)' p.set({ Param::D, 1000.f }, { Param::p, 2000.f });
return 0;
}
不能直接使用
{ Param::D, 1000.f }
在需要推导时作为函数参数。这样做的原因是大括号初始化列表没有类型。因为它没有类型,所以编译器不能推导出类型。你必须帮助它前进。你可以像之前那样指定类型,比如
ChParam{ Param:D, 1000.f }
或者您可以指定期望的对象类型。如果你想要相同类型的变量数,那么std::intializer_list
就可以了。它允许编译器从单个带括号的初始化列表中构造元素。使用它,您的代码将看起来像
PipeCalcParams& set(std::initializer_list<ChParam> args)
调用时使用
p.set({{ Param::D, 1000.f }, { Param::p, 2000.f }})
请注意使用的额外花括号。最外层的集合声明std::intializer_list
,每个内部的集合声明列表中的每个ChParam
。
相关文章:
- 是否可以初始化不可复制类型的成员变量(或基类)
- C++使用整数的压缩数组初始化对象
- C++初始化基类
- 多成员Constexpr结构初始化
- 复制列表初始化的隐式转换的等级是多少
- 内联映射初始化的动态atexit析构函数崩溃
- 如何在C++中初始化嵌套类中的2个memeber
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 没有用于初始化C++中的变量模板的匹配构造函数
- 在未初始化映射的情况下,将值插入到映射的映射中
- C++成员初始化
- 为什么在C++中首先初始化成员类
- 同时具有"聚合初始化"和"模板推导"
- 初始化具有非默认构造函数的std::数组项的更好方法
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 在C和C++中初始化结构中的数组
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- 在函数内部的声明中初始化数组,并在外部使用它
- 继承:构造函数,初始化C++11中基类的类C数组成员