|
Boost : |
From: Douglas Gregor (gregod_at_[hidden])
Date: 2002-05-12 23:33:05
On Sunday 12 May 2002 11:48 pm, you wrote:
> 3) Exists (this can be worked around using the is_member idiom)
"is_member" should have been named "has_member".
Perhaps I spoke too soon. I expected has_member to be obvious given the
previous discussion, but my efforts have been rejected by the compilers I
have access to. My latest attempt is, I believe, correct, although no
compilers seems to agree.
The important part of the implementation is:
template<typename T>
yes_type
has_function_call_operator_helper(type<T>,
truth<(&T::operator() != 0)>* = 0);
no_type has_function_call_operator_helper(...);
The intention is that by comparing &T::operator() against 0 we don't need to
know the type of operator(). Then we bury this comparison in the
instantiation of a template so it happens early enough to block instantiation
of the function template. Idea seems sound, but neither Comeau 4.2.45.2 or
4.3.0 (beta) will instantiate the template. Full code is below, and I'd
appreciate any insight into this little problem that roared:
-----------------------------------------------------------
typedef char yes_type;
typedef double no_type;
template<bool Cond> struct truth {};
template<typename T> struct type {};
template<typename T>
yes_type
has_function_call_operator_helper(type<T>,
truth<(&T::operator() != 0)>* = 0);
no_type has_function_call_operator_helper(...);
template<typename F>
struct has_function_call_operator
{
enum { value = (sizeof(has_function_call_operator_helper(type<F>()))
== sizeof(yes_type)) };
};
struct functor {
void operator()() const;
};
struct not_a_functor {};
int main()
{
int a[has_function_call_operator<functor>::value?1:0];
int b[has_function_call_operator<not_a_functor>::value?0:1];
return 0;
}
-----------------------------------------------------------
Doug
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk