未知类型的可变构造函数参数列表

Posted

技术标签:

【中文标题】未知类型的可变构造函数参数列表【英文标题】:Variadic Constructor Parameter List of Unknown Types 【发布时间】:2017-08-25 13:52:56 【问题描述】:

假设我有一个类旨在表示任何维度的典型数学向量。我想设计这个类,使其构造函数接受任意数量的参数,将这些参数转换为 long double 类型,然后按照参数列表中提供的相同顺序将它们插入“point_list”向量中。

class Pvector

  private:
  std::vector<long double> point_list;

  public:
  // some magic constructor here
;

现在,如果所有参数都属于同一类型,这不会很困难,因为我可以使用初始化列表。但问题是任何参数都可能是不同的类型,这仍然需要接受任意数量的参数(至少一个)。本质上,我试图能够像这样使用构造函数:

int i;
float j;
double k;
long double l;

Pvector vec1(i, j, k, l);
Pvector vec2(k-i, 5, j);
Pvector vec3(i, i, j, j, k, k, l, l);
etc...

我只是不确定是否有可能有一个可变参数构造函数接受多种类型,然后在将它们插入向量之前隐式地将它们转换为长双精度数。是否有可能实现这一点,或者如果我想要一个可变参数构造函数,我的所有参数都必须是相同的类型吗?

【问题讨论】:

您是否考虑过在构造函数中使用std::vector&lt;long double&gt; 并让std::vector 处理它?你必须使用Pvector vec1(i, j, k, l); 我不知道是否可以将parameter packs 与构造函数一起使用,但它可能值得一试。 我不明白是什么问题。 Just do it,不用乱用可变参数模板 另外,我认为它是相关的to this question? 【参考方案1】:

你可以这样做:

class Pvector

public:
  template <typename ...Ts>
  Pvector(Ts && ...ts)
  
    point_list.reserve(sizeof...(Ts));
    init(std::forward<Ts>(ts)...);
  

protected:
private:
  void init()  ;

  template <typename ...Ts>
  void init(long double x, Ts && ...ts)
  
    point_list.push_back(x);
    init(std::forward<Ts>(ts)...);
  

  std::vector<long double> point_list;
;

【讨论】:

事实上,不破坏一些复制/移动构造函数有点棘手。【参考方案2】:

您可能会编写一个模板构造函数(这比较棘手,可以避免匹配 Pvector(Pvector&amp;) 之类的内容。

class Pvector

private:
  std::vector<long double> point_list;

public:
    Pvector() = default;

    Pvector(const Pvector&) = default;
    Pvector(Pvector&&) = default;

    // // SFINAE to avoid to match Pvector(Pvector& t)
    template <typename T,
              typename ... Ts,
              std::enable_if_t<std::is_constructible<std::vector<long double>, T, Ts...>::value
                           && (!std::is_same<Pvector, std::decay_t<T>>::value
                              || sizeof...(Ts) != 0)>* = nullptr>
    Pvector(T&& t, Ts&&... ts) 
    : point_listt, ts... 
    ;

但是只取向量作为参数会更简单

class Pvector

private:
  std::vector<long double> point_list;

public:
    Pvector() = default;

    Pvector(const Pvector&) = default;
    Pvector(Pvector&&) = default;

    Pvector(std::vector<long double>&& v) : point_list(std::move(v)) 
;

并用额外的 调用它

Pvector vec3(i, i, j, j, k, k, l, l);

【讨论】:

以上是关于未知类型的可变构造函数参数列表的主要内容,如果未能解决你的问题,请参考以下文章

C++ 为类模板提供初始化列表构造函数

C语言奇淫技巧之函数的可变参数

C语言中如何实现可变参函数

Scala函数使用可变参数

可变参数模板

函数栈帧与可变参数列表 p1可变参数列表(完结)( C语言从入门到入土(进阶篇)