使用可变参数模板进行统一初始化

Iva*_*ush 4 c++ variadic-templates uniform-initialization c++11

我有一个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;
}
Run Code Online (Sandbox Code Playgroud)

Nat*_*ica 6

它不能直接使用

{ Param::D, 1000.f }
Run Code Online (Sandbox Code Playgroud)

作为需要推导的函数参数.原因是支撑的初始化列表没有类型.由于它没有类型,编译器无法推断出类型.你必须帮助它.你可以做你做的事情并指定类型

ChParam{ Param:D, 1000.f }
Run Code Online (Sandbox Code Playgroud)

或者您可以指定您期望的对象类型.如果你想要一个相同类型的可变数字,那么a std::intializer_list将起作用.它允许编译器从各个支撑的初始化列表构造元素.使用它你的代码看起来像

PipeCalcParams& set(std::initializer_list<ChParam> args)
Run Code Online (Sandbox Code Playgroud)

当你打电话给你时,你会用

p.set({{ Param::D, 1000.f }, { Param::p, 2000.f }})
Run Code Online (Sandbox Code Playgroud)

请注意使用的额外花括号套装.最外面的集合声明了std::intializer_list每个内部集合ChParam在列表中声明每个.