Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do the conditional variable initialization at compiler time?

Tags:

c++

c++11

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?

like image 589
23W Avatar asked Aug 08 '16 14:08

23W


1 Answers

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.

like image 69
Yakk - Adam Nevraumont Avatar answered Feb 11 '23 19:02

Yakk - Adam Nevraumont