Mi*************@tomtom.com wrote:
Just add a test, using the typedef T type; trick again.
template<bool bstruct 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 bstruct test;
template <struct test<true{ };
template <class T, bool b>
struct test_identity : test<b{
typedef T type;
};
template <class Tstruct is_callable {
static const bool value = false;
};
template <class Tclass Constant {
T value;
public:
Constant(T t) : value(t) { }
void operator()()
{ std::cout << "value: " << value << std::endl; }
};
template <class Tstruct is_callable<Constant<T {
static const bool value = true;
};
// T1 and T2 must be callable
template <class T1, class T2class 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,T2if 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<inta = 5; Constant<doubleb = 10.3;
(a+b)();
works, but
Constant<inta = 5;
(a+10.3)();
fails to compile, despite my implicit constructor, since it tries to
make Sum<Constant<int>,intand in doing so, tries to make
test<is_callable<int>::valuewhich is undefined.
I tried one more thing:
template <class T1,class T2>
Sum<T1,T2operator+(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