
On Wed, Jul 27, 2011 at 4:23 PM, Edward Diener <eldiener@tropicsoft.com>wrote:
On 7/27/2011 4:14 PM, Jeffrey Lee Hellrung, Jr. wrote:
On Wed, Jul 27, 2011 at 12:23 PM, Mathias Gaunard< mathias.gaunard@ens-lyon.org> wrote:
On 07/27/2011 07:52 PM, Jeffrey Lee Hellrung, Jr. wrote:
I think you missed the convertibility requirement(s).
TTI needs an exact signature.
...and hence why I had presumed it to be outside of the scope of TTI. It stills falls within the domain of introspection, though.
You need SFINAE for expressions to do this.
You can get a pretty good approximation via something like the following (warning: untested).
-------- struct yes_type { char _dummy[1]; }; struct no_type { char _dummy[2]; };
struct dummy_result_t { }; yes_type is_dummy_result(dummy_result_**t); no_type is_dummy_result(...);
struct base_t { void xxx() { } }; template< void (base_t::*)( )> struct has_mem_fn_detector { typedef no_type type; };
template< class T> struct derived_t : T, base_t { using T::xxx; dummy_result_t xxx(...) const; };
template< class T> typename has_mem_fn_detector< &T::xxx>::type has_mem_fn_test(int); template< class T> yes_type has_mem_fn_test(...); --------
First, you determine if T *has* a member function called xxx, regardless of signature, via
struct derived2_t : T, base_t { }; sizeof( has_mem_fn_test< derived2_t>(0) ) == sizeof( yes_type )
Something is missing here. You have derived2_t as a struct but clearly you mean it as a template class since there is no base class T. But if it is a template class it can not be passed as a type to has_mem_fn_test.
No, I meant it as a plain struct; I'm assuming T is already defined in the enclosing context, i.e., something like template< class T > has_member_function_xxx { struct derived2_t : T, base_t { }; ... check if T::xxx exists via has_mem_fn_test... ... if so, check if T.xxx has a compatible signature ... }; I am interested in what you may be trying to do here, so that is why I am
pointing this out.
Can you correct and explain what you are doing again ? I would like to understand the technique for checking convertibility.
Let me get a full example put together, then.
If what you are doing is similar to what Frederick Bron has for type traits operators, I will check his code instead.
It is similar in spirit, but more of a PITA. BTW, these aren't entirely my original ideas, but I forget where I pilfered them from :/
and, if this passes, then you use the expression declval< derived_t<T>
().xxx(arg0, arg1) (for example) to query, first, whether the type of the
expression is dummy_result_t; then, assuming not, whether the type of the expression has the convertibility properties you desire (for example).
It's not perfect, e.g., it breaks when xxx is private or if you want to check nullary member functions (must resort to exact signatures in that case, I think), and I haven't tested what happens when xxx is a static member function. But I don't think any of this is using SFINAE for expressions.
- Jeff