问题描述
如何将可变参数的构造函数参数存储到vector?
尝试失败的示例:
class Combo
{
public:
template <class... Args>
Combo(Args... args)
{
// this->keys_.push_back(args...);
// this->keys_.push_back(args)...;
// this->keys_.push_back(std::forward<Args>(args...));
//for (uint8_t arg : args...)
// this->keys_.push_back(arg);
// ???
}
private:
std::vector<uint8_t> keys_;
};
解决方法
- C ++ 11
for(auto &&i: {args...}) keys.push_back(std::move(i));
- C ++ 17
(keys.push_back(args),...);
- 哦,对不起,我错过了显而易见的事情:
template<class... Args> Combo(Args... args): keys_{uint8_t(args)...} {}
,
在c++17中使用fold expression,您可能会
#include <vector>
#include <utility> // std::forward
class Combo
{
public:
template <class... Args>
Combo(Args&&... args)
{
keys_.reserve(sizeof...(Args)); // reserve memory for unwanted reallocation
(keys_.emplace_back(std::forward<Args>(args)),...);
}
private:
std::vector<uint8_t> keys_;
};
但是,这将允许传递除uint8_t
之外的其他类型,并且对于那些可以隐式转换为uint8_t
的类型,将进行隐式转换。
这不是期望的行为。因此,我建议如下static_assert
。
#include <type_traits> // std::is_same_v
template <class... Args>
Combo(Args&&... args)
{
// to make sure that the args all are of type `uint8_t`
static_assert((std::is_same_v<uint8_t,Args> && ...),"Args should be uint8_t");
keys_.reserve(sizeof...(Args)); // reserve some memory for unwanted reallocation
(keys_.emplace_back(std::forward<Args>(args)),...);
}
这将为您提供以下错误
Combo obj{ 1,2,3,4.f };
// ^^^^ --> float
,
您可以写:
template <class... Args>
Combo(Args... args)
{
(keys_.push_back(args),...);
}
,
template<typename... Args>
Combo(Args &&... args): keys_ { std::forward<Args>(args)... } {}
甚至更好
Combo(std::initializer_list<uint8_t> keys): keys_(keys) {}