Reputation: 75
How can I store variadic constructor arguments to vector?
Example with my failed tries:
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_;
};
Upvotes: 4
Views: 279
Reputation: 10466
template<typename... Args>
Combo(Args &&... args): keys_ { std::forward<Args>(args)... } {}
Or:
Combo(std::initializer_list<uint8_t> keys): keys_(keys) {}
Upvotes: 1
Reputation: 32722
In c++17 using fold expression, you might do
#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_;
};
However, that will allow one to pass types other than uint8_t
and for those types which can be implicitly converted to uint8_t
, an implicit conversion will take place.
This will not be the desired behaviour. Therefore I would suggest the static_assert
as follows.
#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)), ...);
}
this will give you now an error for the following
Combo obj{ 1, 2, 3, 4.f };
// ^^^^ --> float
Upvotes: 5
Reputation: 11940
for(auto &&i: {args...}) keys.push_back(std::move(i));
(keys.push_back(args), ...);
template<class... Args> Combo(Args... args): keys_{uint8_t(args)...} {}
Upvotes: 5
Reputation: 26066
You can write:
template <class... Args>
Combo(Args... args)
{
(keys_.push_back(args), ...);
}
Upvotes: 1