Как получить параметры функции, кроме первого? - PullRequest
0 голосов
/ 26 мая 2020

Вот моя текущая реализация:

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.

Можно ли использовать только один конструктор?

Так что Dual d2{1.f, 1.f, 1.f}; тоже в порядке.

Может быть, вот так (не может компилироваться):

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.

Должен ли я использовать вариационный шаблон c или std::initilizer_list<> ?

А как пользоваться?

Ответы [ 3 ]

2 голосов
/ 26 мая 2020

Что-то вроде этого должно работать с 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
}
2 голосов
/ 26 мая 2020

Вы можете написать конструктор, который принимает переменное c количество аргументов, например:

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

Вот демонстрация .

С c + +20, вы можете упростить это до:

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

Это имеет то преимущество перед предыдущей версией, что конструктор будет принимать только значения с плавающей запятой. (Несмотря на то, что предыдущая версия предупреждает о сужении конверсий).

Вот демонстрация .

1 голос
/ 27 мая 2020

Как дополнение к уже существующим ответам, вы можете использовать std::initializer_list (C ++ 11). К сожалению, valarray не имеет конструктора с двумя итераторами, что делает код довольно громоздким:

#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.
}
...