C++11 standard have std::conditional<>
template for the type selection by the some boolean condition at compiler time.
How to do the same operation but for select the init value for variable initialization? Similar to type a = (exp) ? first_value : second_value;
.
I use my template:
template<bool B, typename T>
inline constexpr T&& conditional_initialize(T&& i1, T&& i2) {
return B ? std::move(i1) : std::move(i2);
}
But it can be used only for POD types: int a = conditional_initialize<true>(1, 2);
.
For array initialization this template is compiled with error. Wrong compile example: int a[] = conditional_initialize<true>({1, 2}, {3,4,5});
Error message: no matching function for call to 'conditional_initialize(<brace-enclosed initializer list>, <brace-enclosed initializer list>)';
Who can help me with template?
template<class T, std::size_t N, std::size_t M, bool b>
std::array<T, b?N:M>
conditional_array( std::array<T, N>&& lhs, std::array<T, M>&& rhs ) {
return std::move(std::get<b?0:1>( std::tie(lhs, rhs) ) );
}
this gives you:
auto a = conditional_array<int,2,3,true>({{1, 2}}, {{3,4,5}});
which is close.
In general, {}
constructs are not expressions, they cannot be perfectly forwarded through any mechanism through another variable.
We can also get:
auto a = cond_init<true>( make_array(1,2), make_array(3,4,5) );
with a bit more work.
template<bool Test, class A, class B>
std::conditional_t<Test,A,B>
cond_init(A a, B b) {
return std::move( std::get<Test?0:1>( std::tie(a,b) ) );
}
template<class T0, class...Ts>
std::array< std::decay_t<T0>, sizeof...(Ts)+1 >
make_array( T0&& t0, Ts&&...ts ) {
return {{std::forward<T0>(t0), std::forward<Ts>(ts)...}};
}
I didn't make these constexpr
, because lazy.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With