Variadic constexpr selector type

Sorry for the pompous name, I would like to create a function constexprthat takes a variable number of logical arguments to the template and returns the "index of the template" of the first value truein C ++ 11 (C ++ 14 only decisions are welcome, but will not be accepted as an answer).

For example, calling this function Selector

Selector< false, false >() == 0 // none of the template argument is true
Selector< true, false, true >() == 1 // first true template argument is the first one
Selector< false, false, true, false >() == 3 // .. and here it the third one

A typical use of this and the reason I call it a "type selector" would be

Selector< std::is_pointer<T>::value, std::is_arithmetic<T>::value >()

and the reason I would like it to be constexprfor use in a partial specialized specialization.

I'm not quite sure how to do this, although I think that using variable templates, a specialized specialized construction (for case 0) and recursion (is it possible to "consume" template arguments, for example shiftin bash?), This should be feasible.

+4
source share
3 answers

Based on @CoffeeandCode's answer, here is another example that works as expected using constexprrecursion:

#include <iostream>
#include <cstddef>

template<bool B0=false, bool... Bs>
constexpr std::size_t Selector( std::size_t I = 1 )
{
    return B0 ? I : Selector<Bs...>(I+1);
}

template<>
constexpr std::size_t Selector<false>( std::size_t I )
{
    return 0;
}

int main()
{
    std::cout<< Selector() << std::endl;
    std::cout<< Selector<false,false>() << std::endl;
    std::cout<< Selector<true,false,true>() << std::endl;
    std::cout<< Selector<false,false,true,false>() << std::endl;
}
+2
source
#include <cstddef>
#include <type_traits>

template <std::size_t I, bool... Bs>
struct selector;

template <std::size_t I, bool... Bs>
struct selector<I, true, Bs...> : std::integral_constant<std::size_t, I> {};

template <std::size_t I, bool... Bs>
struct selector<I, false, Bs...> : selector<I+1, Bs...> {};

template <std::size_t I>
struct selector<I> : std::integral_constant<std::size_t, 0> {};

template <bool... Bs>
constexpr std::size_t Selector()
{
    return selector<1, Bs...>::value;
}

Demo

+6
source

, constexpr. , , ++ 11, :

#include <cstddef>

template<std::size_t I = 1>
constexpr std::size_t selector(bool value = false){
    return value ? I : 0;
}

template<std::size_t I = 1, typename ... Bools>
constexpr std::size_t selector(bool first, bool second, Bools ... others){
    return first ? I : selector<I+1>(second, others...);
}

, , constexpr - .

+1

Source: https://habr.com/ru/post/1609777/


All Articles