Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SFINAE HasMethod Traits crashes on private methods

25 views
Skip to first unread message

Vinzenz Feenstra

unread,
Apr 5, 2005, 3:45:20 AM4/5/05
to
Hi,
I was asking myself if there is a SFINAE way to avoid the problem with
that code below.

It will check if a class got a Method with a given Signature and Name.
But if the Method is private it crashes while compilation, is there a
way to solve that?

BR

Vinzenz 'evilissimo' Feenstra


[CODE]

#include <iostream>

struct yes{ char _; };
struct no{ char _[2]; };

#define DEFINE_HAS_METHOD( MethodName , MethodTraitsDef )\
template< class ClassType>\
struct MethodName\
{\
static void dummy();\
private:\
MethodTraitsDef\
template <class U>\
static no MethTest(...);\
template <class U>\
static yes MethTest(MethodTraits<U>*);\
public:\
static const bool value = (sizeof(yes) ==
sizeof(MethTest<ClassType>(0)));\
}

// Creating a TraitsType for a Swap Method
#define HasSwap template <class U, U &(U::*Ptr)(U const & ) = &U::Swap> \
struct MethodTraits;

// Defining HasMethodTraits using TraitsType HasSwap
DEFINE_HAS_METHOD( HasMethodSwap , HasSwap );

struct FooBar
{
private:
FooBar & Swap( FooBar const &){ return *this;}
};
struct Foo
{
Foo & Swap( Foo const &){ return *this;}
};
struct Bar
{
Bar & SomeFunc( Bar const &){ return *this;}
};


int main()
{
// Will crash
std::cout << " Has FooBar the method Swap? " << (
HasMethodSwap<FooBar>::value ? " Yes " : " No " ) << std::endl;

// Works fine
std::cout << " Has Foo the method Swap? " << (
HasMethodSwap<Foo>::value ? " Yes " : " No " ) << std::endl;
std::cout << " Has Bar the method Swap? " << (
HasMethodSwap<Bar>::value ? " Yes " : " No " ) << std::endl;
}

[/CODE]

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Vladimir Marko

unread,
Apr 8, 2005, 3:43:51 AM4/8/05
to
Vinzenz Feenstra wrote:
> Hi,
> I was asking myself if there is a SFINAE way to avoid the problem
with
> that code below.
>
> It will check if a class got a Method with a given Signature and
Name.
> But if the Method is private it crashes while compilation, is there a
> way to solve that?
[snip]

I just can't help. I must write that the active core issue
http://www.open-std.org/jtc1/­sc22/WG21/docs/cwg_active.html­#339
questions the validity of all has-member code I've ever seen.

Now to your problem. It comes down to the question whether
access check failure during template overload resolution
should cause deduction failure or compile-time error. IIRC the
standard does _not_ list this in 14.8.2/2 as a reason for
deduction failure thus making any references to inaccessible
or ambiguous members ill-formed.

I've made a lot of test with gcc 3.4.2 around this problem
but it all seems irrelevant when the standard simply rules out
any workaroud I can think of. The only useful output of my
tests is a bug report against gcc i'm about to submit.

Regards,
Vladimir Marko

Branimir Maksimovic

unread,
Apr 8, 2005, 7:17:00 PM4/8/05
to
Vinzenz Feenstra wrote:
> Hi,
> I was asking myself if there is a SFINAE way to avoid the problem
with
> that code below.
>
> It will check if a class got a Method with a given Signature and
Name.
> But if the Method is private it crashes while compilation, is there a
> way to solve that?
>
> #define DEFINE_HAS_METHOD( MethodName , MethodTraitsDef )\
> template< class ClassType>\
> struct MethodName\
> {\
> static void dummy();\
> private:\
> MethodTraitsDef\
> template <class U>\
> static no MethTest(...);\
> template <class U>\
> static yes MethTest(MethodTraits<U>*);\
> public:\
> static const bool value = (sizeof(yes) ==
> sizeof(MethTest<ClassType>(0)));\
> }
>
Nothing more to add except that older versions of gcc
are confused if one referes to templated class itself in enum or static
const member initialization, for example g++ 3.2.2 segfaults no matter
whether
member function is private or not.
Following will cause compile time error, not segfault, thus showing
real error that all MethTest's are instantiated.


#define DEFINE_HAS_METHOD( MethodName , MethodTraitsDef )\

struct MethodName##Tmp{\


MethodTraitsDef\
template <class U>\
static no MethTest(...);\
template <class U>\
static yes MethTest(MethodTraits<U>*);\

};\


template< class ClassType>\
struct MethodName\
{\
static void dummy();\
private:\

public:\
static const bool value = \
(sizeof(yes) ==

sizeof(MethodName##Tmp::MethTest<ClassType>(0)));\
}

Interestingly sun CC 5.6 compiles without error, but always shows 'No'.

Greetings, Bane.

0 new messages