2015-10-01 67 views
4

對不起,自大的名字,我想創建一個constexpr函數,該函數接受可變數量的布爾模板參數,並返回第一true值的「模板指數」,在C++ 11(僅限C++ 14解決方案,但不會被接受爲答案)。可變參數constexpr類型選擇器

例如,調用這個函數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's the third one 

一個典型的利用這個,爲什麼我把它稱爲一個「類型選擇器」的原因,是

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

及原因爲什麼我想要它是一個constexpr是用於部分模板專業化。

我不完全知道如何去這個問題,但我認爲,使用可變參數模板,模板constexpr專業化(爲0的情況下),和遞歸(有沒有可能「消費」模板參數,如shift在bash?),這應該是可行的。

+0

Downvote請解釋... – Sheljohn

+0

這是一個很好的問題。但它缺乏努力...... –

+0

@KarolyHorvath同意,我正試着想出一些東西。 – Sheljohn

回答

2

基於由@CoffeeandCode答案,這裏是使用constexpr遞歸預計工程又如:

#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; 
} 
6
#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

+1

這是美麗的:) – Sheljohn

1

我不滿意的是,答案是不是單純的constexpr功能。所以我重新寫在遞歸一個C++ 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因爲模板參數遞增。

+0

語法略有不同,輸入類型不限於'bool's,但也可以工作:) – Sheljohn