我用两种不同的方式编写了这个模板类:一种使用可变参数构造函数,另一种使用std::initializer_list<T>
。出于这个问题的目的,我将以不同的方式命名类,但请注意,在我的项目中,它是同一个类,因为两个版本都做同样的事情。我想知道这两个版本的好处和缺点是什么。哪一个更有效,为什么?
可变参数版本:
#include <vector>
#include <memory>
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 ) )... }
{}
}; // Nodes
int main() {
int x = 3;
int y = 5;
int z = 7;
Nodes<int> nodes( x, y, z );
return 0;
}
std::initializer_list<T>
版本
#include <vector>
#include <memory>
template<typename T>
class Nodes2 {
private:
unsigned m_numParams;
std::vector<std::shared_ptr<T>> m_vNodes;
public:
Nodes2() : m_numParams(0), m_vNodes{ nullptr } {}
explicit Nodes2( std::initializer_list<T> ini ) :
m_numParams( ini.size() ) {
for ( auto&& e : ini ) {
m_vNodes.push_back( std::make_shared<T>( e ) );
}
}
}; // Nodes2
int main() {
int x = 3;
int y = 3;
int z = 3;
std::initialize_list<int> ini{ x, y, z };
Nodes2<int> nodes2( ini );
return 0;
}
如果您正在创建一个通用容器,并且不知道将要存储的对象类型(T
(,并且您希望允许移动构造,那么可变参数版本更好。
这是因为您无法从std::initializer_list
移动,因此您的第二个版本必须复制构造T
对象。
从cppreference
:
std::initializer_list<T>
类型的对象是一个轻型代理对象,它提供对类型为const T
的对象数组的访问
无法获得对存储的对象数组的可变访问。