【问题标题】:How to get function parameters except the first one?如何获取除第一个之外的函数参数?
【发布时间】:2020-05-26 16:49:51
【问题描述】:

以下是我目前的实现:

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&lt;&gt;

以及如何使用?

【问题讨论】:

  • 您希望所有 4 个版本都使用单个构造函数,还是前 3 个版本足够?
  • 前三个。我会在问题中澄清。

标签: c++ variadic-templates variadic-functions


【解决方案1】:

您可以编写一个带有可变数量参数的构造函数,如下所示:

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,我认为将 auto 参数限制为仅使用概念浮动是有益的。
【解决方案2】:

这样的东西应该适用于 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
}

【讨论】:

    【解决方案3】:

    作为现有答案的补充,您可以使用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.
    }
    

    【讨论】:

      猜你喜欢
      • 2019-07-07
      • 2016-11-08
      • 2017-06-11
      • 1970-01-01
      • 2011-09-11
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 1970-01-01
      相关资源
      最近更新 更多