I have following problem:
I want to determine between two types without actually evaluating the 'resulting' types - since the type may not exist at all - be invalid. (Please no C++11 stuff)
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;
}
Can it somehow be determined? (Assuming that chosen type is always valid, but not chosen type maybe invalid).
Instead of passing the types directly, pass a metafunction which evaluates to the types. This metafunction can then be evaluated lazily within the 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;
}
Use lazy evaluation:
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, a simple rewrite to get rid of the using-aliases is needed, see here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With