help detecting presence of operator[]

Hi all, I'm trying to perform a compile-time check to determine if a class has an operator[]. I'm using a "trick" I think I've seen in Adobe's library and on this list in the past: -------- BEGIN CODE -------- template< class T > struct has_op_bracket { struct base_t { void operator[]( int ); }; struct derived_t : T, base_t { }; template< void (base_t::*)( int ) > struct sfinae { typedef char type; }; template< class U > static typename sfinae< &U::operator[] >::type is_ambiguous(int); template< class U > static int is_ambiguous(...); static const bool value = sizeof( is_ambiguous< derived_t >(0) ) != 1; }; -------- END CODE -------- The way I understand this working is if T has no operator[], then &derived_t::operator[] unambiguously refers to *base_t::operator[], and so the first is_ambiguous overload is selected. Otherwise, &derived_t::operator[] is ambiguous, which is sufficient (I guess...?) for SFINAE to kick in, and the second is_ambiguous overload is selected. Now given the following definitions of X0 and X1: -------- BEGIN CODE -------- struct X0 { }; struct X1 { void operator[](void*); }; -------- END CODE -------- then the following static assertions pass, as expected: -------- BEGIN CODE -------- BOOST_STATIC_ASSERT(( !has_op_bracket<X0>::value )); BOOST_STATIC_ASSERT(( has_op_bracket<X1>::value )); -------- END CODE -------- However, if X2 is defined as -------- BEGIN CODE -------- struct X2 { template< class T > struct R : T { }; template< class T > typename R<T>::type operator[](T); }; -------- END CODE -------- then has_op_bracket<X2>::value fails to compile on MSVC9, but (according to Dinkum Exam[1]) it does compile just fine on "EDG/C++". The error in MSVC9 is -------- BEGIN OUTPUT -------- error C2516: 'T' : is not a legal base class 1> d:\test\main.cpp(9) : see declaration of 'T' 1> d:\test\main.cpp(9) : see reference to class template instantiation 'X2::R<T>' being compiled 1> with 1> [ 1> T=int 1> ] 1> d:\test\main.cpp(21) : see reference to class template instantiation 'has_op_bracket<T>' being compiled 1> with 1> [ 1> T=X2 1> ] -------- END OUTPUT -------- generated by the following program: -------- BEGIN CODE -------- template< class T > struct has_op_bracket { struct base_t { void operator[]( int ) const; }; struct derived_t : T, base_t { }; template< void (base_t::*)( int ) const > struct sfinae { typedef char type; }; template< class U > static typename sfinae< &U::operator[] >::type is_ambiguous(int); template< class U > static int is_ambiguous(...); static const bool value = sizeof( is_ambiguous< derived_t >(0) ) != 1; // line 9 }; struct X2 { template< class T > struct R : T { }; template< class T > typename R<T>::type operator[](T); }; int main() { has_op_bracket<X2>::value; // line 21 return 0; } -------- END CODE -------- What I don't understand is why MSVC is trying to instantiate R<int>. It seems to be grabbing the int from the parameter type of the member function pointer template parameter in sfinae, which doesn't seem like the right thing to do. I can change that parameter to anything else (as long as it doesn't have a nested type typedef) and the error persists. Is MSVC correct, or is this a compiler bug? Either way, is there an alternative, more portable approach to achieve the desired effect? Thanks in advance, - Jeff [1] http://www.dinkumware.com/exam/default.aspx

Jeffrey Hellrung wrote:
Hi all,
I'm trying to perform a compile-time check to determine if a class has an operator[]. I'm using a "trick" I think I've seen in Adobe's library and on this list in the past: In the vautl I uplaoded a macro to generate the needed meta-function for such method/operator test. Take a look at introspection.zip, especially the has_member_function.hpp file.
-- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35

joel falcou wrote:
Jeffrey Hellrung wrote:
Hi all,
I'm trying to perform a compile-time check to determine if a class has an operator[]. I'm using a "trick" I think I've seen in Adobe's library and on this list in the past: In the vautl I uplaoded a macro to generate the needed meta-function for such method/operator test. Take a look at introspection.zip, especially the has_member_function.hpp file.
That isn't *quite* what I need. I'm aiming to detect the presence of operator[] (or any other member function, for that matter) independent of its precise signature (and it looks like the macros that has_member_function.hpp defines need a signature). Do you have anything that will help in that regard? Thanks for the reference though, this might come in handy ;) - Jeff

Jeffrey Hellrung wrote:
That isn't *quite* what I need. I'm aiming to detect the presence of operator[] (or any other member function, for that matter) independent of its precise signature (and it looks like the macros that has_member_function.hpp defines need a signature). Do you have anything that will help in that regard? Oh, without giving out a signature is indeed a challenge. I'll take a deeper look then
-- ___________________________________________ Joel Falcou - Assistant Professor PARALL Team - LRI - Universite Paris Sud XI Tel : (+33)1 69 15 66 35
participants (2)
-
Jeffrey Hellrung
-
joel falcou