2012-05-23 5 views
6

Interesuje mnie trochę nauka na temat meta-programowania szablonów. W poniższym kodzie próbuję znaleźć niepodpisany typ całki wystarczająco duży, aby pomieścić N bitów, określonych w czasie kompilacji, używając rekursji szablonów.Odliczanie typu rekurencyjnego C++

template <typename T> 
struct NextIntegralType 
{ 
}; 

template <> 
struct NextIntegralType<void> 
{ 
    typedef unsigned char type; 
}; 

template <> 
struct NextIntegralType<unsigned char> 
{ 
    typedef unsigned short type; 
}; 

...More type 'iteration' here... 

template<size_t BITS, typename T> 
struct FindIntegralType2 
{ 
    typedef std::conditional<BITS <= sizeof(typename T::type)*8, T, FindIntegralType2<BITS, NextIntegralType<typename T::type>>> _type; 
    typedef typename _type::type type; 
}; 

template<size_t BITS> 
struct FindIntegralType 
{ 
    typedef typename FindIntegralType2<BITS, NextIntegralType<void>>::type type; 
}; 

Kiedy zadeklarować zmienną i przypisać do niego wartość integralną ...

FindIntegralType<15>::type test(4000); 

uzyskać następujące:

error: no matching function for call to ‘FindIntegralType2<15u, NextIntegralType<unsigned char> >::FindIntegralType2(int)’ 
note: candidates are: 
note: constexpr FindIntegralType2<15u, NextIntegralType<unsigned char> >::FindIntegralType2() 
note: candidate expects 0 arguments, 1 provided 
note: constexpr FindIntegralType2<15u, NextIntegralType<unsigned char> >::FindIntegralType2(const FindIntegralType2<15u, NextIntegralType<unsigned char> >&) 
note: no known conversion for argument 1 from ‘int’ to ‘const FindIntegralType2<15u, NextIntegralType<unsigned char> >&’ 

Wydaje się, że nie jest moim rekursji " odwijanie ". Czy ktoś może wskazać mi właściwy kierunek? Uwaga: Używam GCC 4.6.

EDIT:
znalazłem post, że brakowało mi wcześniej:
Automatically pick a variable type big enough to hold a specified number

co wskazuje na odpowiedź na impuls (gdzie oni zawsze są):
boost_integer

To powinno rozwiązać zarówno moją praktyczną potrzebę, jak i intelektualną ciekawość.

+0

Dlaczego nie używasz stdint.h? – mfontanini

+0

@mfontanini Czy mógłbyś rozwinąć? – TractorPulledPork

Odpowiedz

2

Twój problem polega na tym, że _type::type ma wartość std::conditional<...>::type, a nie FindIntegralType2<...>::type. Zmień go na typedef typename _type::type::type type; (za dużo type x_X). To powinno rozwiązać twój problem.

+0

To się zgadza. Dziękuję Ci! – TractorPulledPork