可变参数模板的统一初始化 [英] uniform initialization with variadic templates
问题描述
我有一个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});
I have a POD ChParam
and it's a parameter in the variadic template function set
. I'd like to pass to function arguments(constructor parameters) in curly braces p.set({ Param::D, 1000.f }, { Param::p, 2000.f })
. And thought that the constructor will be called implicitly and the ChParam
objects will be created. But it's impossible, I should explicitly create an object 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 }
作为需要推论的函数参数.这样做的原因是初始化列表列表没有类型.由于没有类型,因此编译器无法推断类型.您必须一直提供帮助.您可以执行您的操作并指定类似的类型
as a function parameter when it needs to be deduced. The reason for this is a braced initializer list has no type. Since it does not have a type, a type cannot be deduced by the compiler. You have to help it along. You can do what you did and specify the type like
ChParam{ Param:D, 1000.f }
或者您可以指定所需的对象类型.如果要使用相同类型的变量号,请使用 std :: intializer_list
会起作用.它允许编译器从单独的支撑式初始化列表中构造元素.使用该代码看起来像
Or you can specify the type of object you are expecting. If you want a variable numbers of the same types then a std::intializer_list
will work. It allows the compiler to construct the elements from the individual braced initializer lists. Using that your code would look like
PipeCalcParams& set(std::initializer_list<ChParam> args)
当您调用它时,您将使用
And when you call it you would use
p.set({{ Param::D, 1000.f }, { Param::p, 2000.f }})
请注意使用的花括号的额外集合.最外面的集合声明 std :: intializer_list
,每个内部集合声明列表中的每个 ChParam
.
Do note the extra set of curly braces used. The outermost set declares the std::intializer_list
and each inner set declares each ChParam
in the list.
这篇关于可变参数模板的统一初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!