How to define between two C ++ types without instantiating types?

I have the following problem:

I want to define between two types without actually evaluating the "resulting" types - since the type may not exist at all - is invalid. (Please do not use C ++ 11)

Example:

#include <iostream> #include <iterator> template <bool B, typename T, typename F> struct TemplateIf { }; template <typename T, typename F> struct TemplateIf<true, T, F> { typedef T Result; }; template <typename T, typename F> struct TemplateIf<false, T, F> { typedef F Result; }; int main(int argc, char** argv) { // On GCC this is error as std::iterator_traits<int>::value_type doesn't exist typename TemplateIf<true, int, std::iterator_traits<int>::value_type >::Result a; a = 5; std::cout << a << std::endl; return 0; } 

Is there any way to determine this? (Assuming the selected type is always valid, but not the selected type may be invalid).

+4
source share
2 answers

Instead of passing types directly, pass a metafunction that evaluates types. Then this metafung can be evaluated lazily within an if.

 #include <iostream> #include <iterator> template <bool B, typename T, typename F> struct TemplateIf {}; template <typename T, typename F> struct TemplateIf<true, T, F> { typedef typename T::type Result; }; template <typename T, typename F> struct TemplateIf<false, T, F> { typedef typename F::type Result; }; template <typename T> struct get_value_type { typedef typename std::iterator_traits<T>::value_type type; }; template <typename T> struct identity { typedef T type; }; int main(int argc, char** argv) { TemplateIf<true, identity<int>, get_value_type<int> >::Result a; a = 5; std::cout << a << std::endl; return 0; } 
+4
source

Use a lazy rating:

 template<class T> using Apply = typename T::type; template<class T> struct identity{ using type = T; }; template<bool B, class T, class F> struct lazy_if{ using type = Apply<T>; }; template<class T, class F> struct lazy_if<false, T, F> : lazy_if<true, F, T>{}; template<class T> struct lazy_iterator_value_type{ using type = typename std::iterator_traits<T>::value_type; }; 

Live example (C ++ 11). For C ++ 03, simple processing is required to get rid of smoothing aliases, see here .

+4
source

All Articles