【问题标题】: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++ function parameters template-classes


【解决方案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 中涉及的主题有点太宽泛了。它也与您的直接问题无关。
  • 好吧,还是谢谢你。你是对的,我的问题并不是立即需要的,但这是我想要理解我还不理解的事情的方式;)。我去网上看看!
猜你喜欢
  • 2018-07-25
  • 2010-11-28
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 2022-06-23
  • 1970-01-01
  • 2012-07-07
  • 2015-10-10
相关资源
最近更新 更多