【问题标题】:Class template with variadic constructor; storing parameters into std::vector< std::shared_ptr<> >带有可变构造函数的类模板;将参数存储到 std::vector< std::shared_ptr<> >
【发布时间】:2016-02-12 20:49:21
【问题描述】:

我正在尝试设计一个类模板,其中它的构造函数有一个可变参数构造函数,并且每个参数类型必须是相同的数据类型。然后我想将所有参数存储到 std::vector&lt; std::shared_ptr&lt;T&gt; &gt; 容器中。如果没有传入参数,那么vector&lt;&gt; 中的第一个shared_ptr&lt;&gt; 将被设置并存储为nullptr。此外,我希望能够跟踪传入了多少参数。到目前为止,这是我尝试过的。

声明

template<typename T>
class Nodes {
private:
    unsigned m_numParams;
    std::vector<sstd::shared_ptr<T>> m_vNodes;

public:
    explicit Nodes( T... );  // Not sure how to set first parameter as being default to nullptr along with the variadic syntax.

};

定义

template<typename T>
Nodes<T>::Nodes( T... ) {

    if ( /* no parameters passed in or 1st parameter is nullptr */ ) {
        T* ptr = nullptr;
        m_vNodes.push_back( ptr );
    } else {
        for each ( /* parameter with same data type */ ) {
            std::shared_ptr<T> sptr( new T() );
            m_vNodes.push_back( sptr );
        }
    }
    m_numParams = m_vNodes.size();
}

我对基本模板的理解还不错,但我对可变参数函数或模板的使用有限,我正在尝试学习新方法以进一步提高我在 c++ 语言中的整体技能。我想知道我的初始方法在逻辑上是否是正确的路径;如果这个概念是可能实现的,如果是这样,实现这一点的最有效方法是什么,所以当我使用这个类模板时,这就是我所期望的并且实际上会发生,如下面的例子所示:

#include "SomeHeader.h"

int main() {

    int x = 3;
    int y = 5;
    int z = 7;

    Nodes<int> someNodes( x, y, z );

    return 0;
}

内部节点私有成员变量将有shared_ptr&lt;int&gt; where

Nodes::m_vNodes[0] = address of x with value 3 stored
Nodes::m_vNodes[1] = address of y with value 5 stored
Nodes::m_vNodes[2] = address of z with value 7 stored

如果没有传递参数...

#include "SomeHeader.h"

int main() {

    Nodes<int> someNodes();

    return 0;
}

内部成员变量将在 vector[0] 位置存储一个“nullptr”。我是否还需要实现其默认构造函数 Nodes();或者这一切都可以通过一个构造函数来实现?

一旦我让这个构造函数正常工作,我就可以毫无问题地继续编写函数或方法来添加、删除、检索、存储、排列或排序数据、比较数据或操作数据。我一直在这里和那里搜索,似乎没有找到任何与我正在寻找的东西相关的东西。任何提示、建议、帮助、链接或示例都将不胜感激,并提前感谢您。

【问题讨论】:

  • 听起来你可能想要std::initializer_list
  • @NathanOliver 我确实喜欢您的评论,并感谢您的建议或提示。但是,我试图看看如何以我最初询问的方式完成此操作。我正在尝试学习可变参数函数/可变参数模板等。

标签: c++ templates constructor shared-ptr variadic-functions


【解决方案1】:

initializer_list 似乎是一个更好的选择,但是对于可变参数模板,它应该是这样的:

template<typename T>
class Nodes {
private:
    unsigned m_numParams;
    std::vector<std::shared_ptr<T>> m_vNodes;

public:
    Nodes() : m_numParams(0), m_vNodes{nullptr} {}

    template <typename ... Ts>
    explicit Nodes( Ts&&...ts) :
        m_numParams(sizeof...(Ts)),
        m_vNodes{std::make_shared<T>(std::forward<Ts>(ts))...}
    {}
};

initializer_list:

explicit Nodes(std::initializer_list<T> ini) :
    m_numParams(ini.size())
{
    for (auto&& e : ini) {
        m_vNodes.push_back(std::make_shared<T>(e));
    }
}

Demo

【讨论】:

  • 感谢您的及时答复;它工作正常。语法对我来说是新的,我还没有使用 make_shared( forward() ) 所以这是一个很大的帮助,不仅仅是让它工作,而且有助于理解如何编写可变参数函数/模板。这很好,干净,紧凑。我想要这个结构而不是初始化列表的原因是我已经使用这些成员作为共享指针存储在向量中。现在,如果这可以用 std::initializer_list 的另一种方法来完成;那么我也愿意接受替代方案。
  • 当我尝试在我的 miain.cpp 文件中使用 std::initialize_list 版本的构造函数时,我将整数变量 x,y,z 传递给节点的构造函数,它不会为我;我不确定如何在我的应用程序中使用这个版本;你能给我举个例子吗?
  • 在我的 main.cpp 中进行了一些试验和错误之后,我终于得到了 std::initializer_list 版本的工作。我必须这样创建它的一个实例:std::initializer_list&lt;int&gt; ini{ x, y, z}; 并将其传递给Nodes 构造函数。
  • @FrancisCugler:我为std::initializer_list添加了一个演示链接。
  • 谢谢;但经过一段时间的反复试验,我能够弄清楚。我还是会看看你提供的链接。
猜你喜欢
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2014-05-09
  • 1970-01-01
  • 1970-01-01
  • 2022-01-05
  • 1970-01-01
相关资源
最近更新 更多