如何获取第一个参数以外的函数参数?
How to get function parameters except the first one?
以下是我目前的实现:
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.
我应该使用可变参数模板还是 std::initilizer_list<>
?
以及如何使用?
您可以编写一个接受可变数量参数的构造函数,如下所示:
template<typename ...Ts>
Dual(float v, Ts ...ts) : v(v), d({ts...}) {}
这里是 demo。
使用 c++20,您可以将其简化为:
Dual(float v, std::floating_point auto ...ts) : v(v), d({ts...}) {}
这比以前的版本有优势,构造函数将只接受浮点值。 (尽管之前的版本会警告关于缩小转换范围)。
这里是 demo。
像这样的东西应该适用于 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
}
作为对现有答案的补充,您可以使用 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.
}
以下是我目前的实现:
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.
我应该使用可变参数模板还是 std::initilizer_list<>
?
以及如何使用?
您可以编写一个接受可变数量参数的构造函数,如下所示:
template<typename ...Ts>
Dual(float v, Ts ...ts) : v(v), d({ts...}) {}
这里是 demo。
使用 c++20,您可以将其简化为:
Dual(float v, std::floating_point auto ...ts) : v(v), d({ts...}) {}
这比以前的版本有优势,构造函数将只接受浮点值。 (尽管之前的版本会警告关于缩小转换范围)。
这里是 demo。
像这样的东西应该适用于 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
}
作为对现有答案的补充,您可以使用 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.
}