是否可以将函数参数存储为某种列表

Posted

技术标签:

【中文标题】是否可以将函数参数存储为某种列表【英文标题】:Is it possible to store function parameters as some kind of list 【发布时间】:2017-11-19 11:48:45 【问题描述】:

我有一个基类

template<class T>
class Base

public:
    Base(T foo = T())
    
        for(int i = 0; i < 10; i++)
            foos.push_back(foo);
    

private:
    std::vector<T> foos;

我有一个派生类

class Derived : public Base<Bar>

public:
    Derived() : Base(Bar("somerandomparameter")) 

我想要这样做,是使用提供的构造函数(不管它是什么)创建一个包含 10 个新 Bars 的向量。

我曾想过创建一个自定义复制构造函数,但这并没有按预期工作,因为 push_back 方法似乎创建了更多副本,至少我的 Bar 构造函数被调用了 10 次以上。

对我来说,最佳解决方案是传递参数列表,因为这只会创建我想要的 10 个对象。

...
Base(ParameterList l)

    for(int i = 0; i < 10; i++)
        foos.push_back(T(l));

...

但由于这是一个模板类,我需要该列表适应T 需要的任何类型或数量的参数。有没有办法做到这一点,或者你知道做我想做的更好的方法吗?

【问题讨论】:

C++11 接受variadic templates。您可以指定标准 c++ 【参考方案1】:

模板类可以有更多的模板构造函数。在您的情况下,您需要一个接受参数包并进行(非完美)转发的人:

template<class T>
class Base

  std::vector<T> foos;

public:
    template<typename... Args>
    Base(Args&&... args)
    
        foos.reserve(10);
        for(int i = 0; i < 10; i++)
            foos.emplace_back(args...);
      
;

应该这样做。只需在Derived 类的构造函数中将参数传递给Base&lt;Bar&gt; 的构造函数即可。

我强调非完美转发的原因是,如果我们 std::forward 将参数放入插入的第一个项目中,它可能会移动它们,从而使它们对第二个无效。 YMMV,您应该仔细考虑这一点。

【讨论】:

哇,非常感谢!它就像一个魅力!你能向像我这样的初学者解释最后一段吗? ;) 我不太明白什么是转发(只是它与左值和右值有关?) @po0l - 调用reserve 是为了从一开始就有10 个元素的空间。这样,当我们插入时,向量就不必重新分配任何东西。我的最后一段涉及implications of perfect forwarding。恐怕在 cmets 中涉及的主题有点太宽泛了。它也与您的直接问题无关。 好吧,还是谢谢你。你是对的,我的问题并不是立即需要的,但这是我想要理解我还不理解的事情的方式;)。我去网上看看!

以上是关于是否可以将函数参数存储为某种列表的主要内容,如果未能解决你的问题,请参考以下文章

将一个值列表而不是多个参数传递给函数?

jQuery使用参数淡入淡出功能

我可以使用map将参数的元组(或列表)插入函数吗?

将数组转换为函数参数列表 [重复]

Python函数可选参数-可以添加为条件吗?

将列表解析为另一个函数参数 - Python