chaosink
chaosink

Reputation: 1483

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?

Upvotes: 0

Views: 75

Answers (3)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123094

Just as an addition to the already existing answers, you can use a std::initializer_list (C++11). Unfortunately valarray has no constructor taking two iterators, which makes the code rather unwieldy:

#include <valarray>
#include <initializer_list>

struct Dual {
    float v;
    std::valarray<float> d;
    Dual(std::initializer_list<float> in) : v(*in.begin()),
        d(in.size() < 2 ? std::valarray<float>() : 
                          std::valarray<float>(&(*(in.begin()+1)),in.size()-1))
    {}
};


int main() {

    Dual d0{1.f};              // OK.
    Dual d1{1.f, 1.f};         // OK.
    Dual d2{1.f, 1.f, 1.f};    // OK.
}

Upvotes: 1

cigien
cigien

Reputation: 60268

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.

Upvotes: 2

Amir Kirsh
Amir Kirsh

Reputation: 13832

Something like this should work with C++20:

class Dual {
    float v;
    std::valarray<float> d;
public:
    Dual(float f, std::floating_point auto... f2)
    : v {f}, d{static_cast<float>(f2)...}  {}
};

int main() {
    Dual f1 {1.5};
    Dual f2 {1.5, 2.5};
    Dual f3 {1.5, 2.5, 3.5};
    // Dual f4 {1.5, 2.5, "3.5"}; // won't compile, type mismatch
}

Upvotes: 2

Related Questions