Re: limiting a template class to certain types ?
Michiel.Salters@tomtom.com wrote:
Just add a test, using the typedef T type; trick again.
template<bool b> struct test; // undefined
template<> struct test<true> { }; // defined specialization
template<typename T, bool b>
struct test_identity<T> : test<b> {
typedef T type;
};
template<class T>
increment_return_type<test_identity<T,
allowed_p<T>::value>::type>::type
operator++(T x);
That's a neat trick. Unfortunately, it doesn't quite do what I need.
Here is a small example:
/* BEGIN CODE */
#include <iostream>
template <bool b> struct test;
template <> struct test<true> { };
template <class T, bool b>
struct test_identity : test<b> {
typedef T type;
};
template <class T> struct is_callable {
static const bool value = false;
};
template <class T> class Constant {
T value;
public:
Constant(T t) : value(t) { }
void operator()()
{ std::cout << "value: " << value << std::endl; }
};
template <class T> struct is_callable<Constant<T> > {
static const bool value = true;
};
// T1 and T2 must be callable
template <class T1, class T2> class Sum {
T1 t1; T2 t2;
public:
Sum(T1 _t1, T2 _t2) : t1(_t1), t2(_t2) { }
void operator()() { t1(); t2(); }
};
template <class T1,class T2>
typename test_identity<Sum<T1,T2>,is_callable<T1>::value &&
is_callable<T2>::value>::type
operator+(T1 t1,T2 t2) {
return Sum<T1,T2>(t1,t2);
}
/* END CODE */
Basically, it only makes sense to have Sum<T1,T2> if T1 and T2 are both
callable. I could easily insert a Boost static assert to ensure that
they are, but my issue is this: the overloaded operator+ still allows
any type to be sent to it, and then generates a compiler error if it's
not callable. So,
Constant<int> a = 5; Constant<double> b = 10.3;
(a+b)();
works, but
Constant<int> a = 5;
(a+10.3)();
fails to compile, despite my implicit constructor, since it tries to
make Sum<Constant<int>,int> and in doing so, tries to make
test<is_callable<int>::value> which is undefined.
I tried one more thing:
template <class T1,class T2>
Sum<T1,T2> operator+(typename
test_identity<T1,is_callable<T1>::value>::type t1,
typename test_identity<T2,is_callable<T2>::value>::type t2) {
return Sum<T1,T2>(t1,t2);
}
but then my main() wouldn't compile because it couldn't implicitly
figure out that test_identity<T1,...>::type was really just T1.
Hopefully I've made my problem more clear. Thanks to those still
paying attention. Any ideas?
steve