Search code examples
c++variadic-templatesvariadic-functions

How to get function parameters except the first one?


The following is my present implementation:

struct Dual {
    float v;
    std::valarray<float> d;

    Dual(float v, std::valarray<float> d): v(v), d(d) {}
    Dual(float v, float d = 0.f): v(v), d({d}) {}
};

Dual d0{1.f};              // OK.
Dual d1{1.f, 1.f};         // OK.
// Dual d2{1.f, 1.f, 1.f}; // Error. I want this.
Dual d2{1.f, {1.f, 1.f}};  // OK.    I don't want this.

Is it possible to use only one constructor?

So that Dual d2{1.f, 1.f, 1.f}; is also OK.

Maybe like this (cannot compile):

struct Dual {
    float v;
    std::valarray<float> d;

    Dual(float v, float d...): v(v), d({d...}) {}
};

Dual d0{1.f};
Dual d1{1.f, 1.f};
Dual d2{1.f, 1.f, 1.f}; // I want this.

Should I use variadic template or std::initilizer_list<>?

And How to use?


Solution

  • You can write a constructor that takes a variadic number of arguments, like this:

    template<typename ...Ts>
    Dual(float v, Ts ...ts) : v(v), d({ts...}) {}
    

    Here's a demo.

    With c++20, you could simplify this to:

    Dual(float v, std::floating_point auto ...ts) : v(v), d({ts...}) {}
    

    This has the advantage over the previous version, that the constructor will only accept floating point values. (Even though the previous version will warn about narrowing conversions).

    Here's a demo.