Reputation: 5951
I would like to insert as many zeros into a vector as there are arguments to a variadic templated function (i.e. number of arguments zeros into a vector). I am trying to use fold expressions to achieve this and it works when using (vec.push_back(zeroHelper(args)), ...);
.
What I do not understand: Why does it not work when I try to initialize the vector directly by "unfolding" into an initializer list like follows:
std::vector<int> vec = { (zeroHelper(args), ...) };
?
Full source code:
template <typename T>
T zeroHelper (T a) { return T{0}; }
template<typename ...Args>
void printer(Args&&... args) {
std::vector<int> vec; // = { (zeroHelper(args), ...) };
(vec.push_back(zeroHelper(args)), ...);
for (auto i : vec) {
std::cout << i << '\n';
}
}
int main()
{
printer(1, 2, 3, 4);
return 0;
}
And here's the source on OnlineGDB.
Expected output:
0
0
0
0
Output with the initializer list approach:
0
Why?
Upvotes: 4
Views: 2492
Reputation: 1998
This one works:
#include <tuple>
#include <vector>
template <typename... Ts>
class Something {
public:
explicit Something(size_t size) : m_vectors{(sizeof(Ts), size)...} {}
auto operator[](size_t idx) noexcept {
return apply(
[&](auto &...vectors) { return std::tie(vectors[idx]...); },
m_vectors);
}
private:
std::tuple<std::vector<Ts>...> m_vectors;
};
int main() {
Something<int, char> qwe(42);
return get<1>(qwe[3]);
}
Upvotes: 0
Reputation: 66230
Because in
std::vector<int> vec = { (zeroHelper(args), ...) };
the parentheses return only one element, the last one; the comma operator discard the precedings.
You should write
std::vector<int> vec = { zeroHelper(args) ... };
to maintains all elements.
In
(vec.push_back(zeroHelper(args)), ...);
the parentheses activate the folding, the comma discards all elements except the last one but the push_back()
operation is applied to vec
for every args...
elements.
Observe also that, using the discarding propriety of the comma operator, you don't need zeroHelper()
at all
You can write
std::vector<int> vec { ((void)args, 0)... };
or
(vec.push_back(((void)args, 0)), ...);
Upvotes: 10