How to Initialize All Tuple Elements by the Same Arguments

How to initialize all tuple elements by the same arguments?

The clearest way is just to construct each element in the tuple constructor argument list:

template <typename... TElements>
struct Container {
Container(Foo foo, Bar bar)
: tuple(TElements{foo, bar}...)
{}
std::tuple<TElements...> tuple;
};

This will result in move (or copy) constructing each element of the tuple from its corresponding constructor parameter; if this is unacceptable you could use piecewise construction:

template <typename... TElements>
struct Container {
Container(Foo foo, Bar bar)
: tuple(std::piecewise_construct, (sizeof(TElements), std::tie(foo, bar))...)
{}
std::tuple<TElements...> tuple;
};

Unfortunately in this case we have to do some kind of gymnastics (here sizeof and a comma operator) to get the variadic list TElements mentioned and ignored.

Initialize tuple with same parameter

Something like this:

template <class... args>
std::tuple<args...> tuplemaker(int n)
{
return std::make_tuple(args(n)...);
}

Live example here.

How to initialize elements of a tuple with one common parameter in a constructor initializer list in c++11?

Issue is resolved. Even the trivial construction in the constructor initializer list works like you'd expect:

Base() :
tuple{*this, *this, *this, *this,
*this, *this, *this}
{}

One of the types had a badly declared constructor, I didn't deduce this from these two error messages at first.

Construct tuple by passing the same argument to each element with explicit constructor

In C++ 14, there doesn't seem to be any way of initializing tuple elements when constructors are explicit, because of the is_convertible requirement. I ended up writing a bare-bones implementation of std::tuple myself that is used on C++14 implementations, such as on Debian 8.

Initialize std::tuple with variadic arguments in constructor

The first implementation looks better to me, because you don't have to repeat yourself by providing the function arguments twice.
Because you set the return type to bool, I would recommend changing the name of the class to Predicate, which is a well known term to describe functions that return boolean values.

Note that std::function can take parameter packs as template parameters too, so you can also do this:

std::function<func_ret_ty(FuncArgs...)> m_Function;

How to initialize tuple of vectors out of a variadic template pack and list of objects which use the same template types?

Not exactly as you asked... with a variadic list of elements instead of an initializer list... but adding an helper method, should works as follows

template <typename T, typename ... Ems>
static std::vector<T> getVect(Ems const & ... ems)
{ return { get<T>(ems)... }; }

template <typename ... Ems>
EmitterMemory (Ems const & ... ems)
: components { getVect<Ts>(ems...)... }
{ }

Obviously you have to initialize memory

auto memory = EmitterMemory<Position, Shoot, Active>(e1, e2); 

without brackets.

If you really want to use a std::initializer_list (but why?) you can send it to getVect() and unpack it inside the body of the method with a classic range-for.

Unrequested Bonus

Using the variadic constructor, you can add an explicit deduction guide

template <typename ... Es, typename ... Ts>
EmitterMemory (TEmitter<Es...>, Ts...) -> EmitterMemory<Es...>;

so you can initialize memory simply as follows

auto memory = EmitterMemory(e1, e2);

because the is_main_components... Ts template parameters (Position, Shoot, Active, in this case) are deduced from the first argument (e1).

Obviously this works if you initialize memory with at least an argument.

Expand tuple to parameters pack in member initializer lists

I found a solution based in this answer, turns out that it is achievable using std::make_index_sequence and std::get.

An auxiliary function that "unwraps" the tuple is required but it can be defined as a private constructor:

#include <tuple>

template<typename Tuple>
using make_tuple_index_sequence = std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>;

template<class Base>
class WithTupleConstructor : public Base // Sort of a Mixin class template
{
public:

// Passing tuple and index sequence to auxiliary constructor
template<class Tuple>
WithTupleConstructor(const Tuple& base_args)
: WithTupleConstructor(base_args, make_tuple_index_sequence<Tuple>{})
{}

private:

// Expanding tuple using std::get
template<class Tuple, std::size_t ...tuple_n>
WithTupleConstructor(const Tuple& base_args, std::index_sequence<tuple_n...> )
: Base(std::get<tuple_n>(base_args)...)
{}
};

class WithCopyConstructor
{
public:

WithCopyConstructor(int a, int b)
{}
WithCopyConstructor(const WithCopyConstructor& other)
{}
};

class WithoutCopyConstructor
{
public:

WithoutCopyConstructor(int a)
{}
WithoutCopyConstructor(const WithoutCopyConstructor& other) = delete;
};

int main()
{
WithTupleConstructor<WithCopyConstructor> m1(std::make_tuple(1,2));

WithTupleConstructor<WithoutCopyConstructor> m2(std::make_tuple(1));
}

This can be further extended to support rvalues and perfect forwarding by adding && and std::forward when receiving and passing the tuples.



Related Topics



Leave a reply



Submit