Connecting Tech Pros Worldwide Forums | Help | Site Map

Ascertaining whether T::reference exists.

Angus Leeming
Guest
 
Posts: n/a
#1: Jul 22 '05
I'm trying to write some class templates to ascertain whether a given
class defines a given member type.

I have been using SFINAE and the "sizeof trick" to do so and, in
general, all works well. The code snippet, below, demonstrates my
problem however. The test fails when I try and ascertain whether the
class defines a "reference" member type because I cannot declare a
pointer to a reference. Uncommenting the penultimate line of code
will result in the compiler telling me just that. Fair enough and
understood.

My question is simply "how should I proceed"?

Kind regards,
Angus


#include <iostream>
#include <vector>

typedef char One;
typedef struct { char a[2]; } Two;

template <typename T>
One has_value_type(typename T::value_type const *);

template <typename T>
Two has_value_type(...);

template <typename T>
One has_reference(typename T::reference const *);

template <typename T>
Two has_reference(...);

int main()
{
typedef std::vector<int> IntVec;

std::cout << "IntVec has value_type? "
<< (sizeof(has_value_type<IntVec>(0)) == 1)
<< std::endl;

std::cout << "IntVec has reference? "
<< (sizeof(has_reference<IntVec>(0)) == 1)
<< std::endl;

//has_value_type<IntVec>((IntVec::reference const *)0);
return 0;
}


tom_usenet
Guest
 
Posts: n/a
#2: Jul 22 '05

re: Ascertaining whether T::reference exists.


On Wed, 4 Feb 2004 13:48:58 +0000 (UTC), Angus Leeming
<angus.leeming@btopenworld.com> wrote:
[color=blue]
>I'm trying to write some class templates to ascertain whether a given
>class defines a given member type.
>
>I have been using SFINAE and the "sizeof trick" to do so and, in
>general, all works well. The code snippet, below, demonstrates my
>problem however. The test fails when I try and ascertain whether the
>class defines a "reference" member type because I cannot declare a
>pointer to a reference. Uncommenting the penultimate line of code
>will result in the compiler telling me just that. Fair enough and
>understood.
>
>My question is simply "how should I proceed"?[/color]
[color=blue]
>template <typename T>
>One has_reference(typename T::reference const *);[/color]

template <typename T>
One has_reference(typename T::reference (*)());

Tom

C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Rob Williscroft
Guest
 
Posts: n/a
#3: Jul 22 '05

re: Ascertaining whether T::reference exists.


Angus Leeming wrote in news:bvqt8a$6dq$1@titan.btinternet.com:
[color=blue]
> I'm trying to write some class templates to ascertain whether a given
> class defines a given member type.
>
> I have been using SFINAE and the "sizeof trick" to do so and, in
> general, all works well. The code snippet, below, demonstrates my
> problem however. The test fails when I try and ascertain whether the
> class defines a "reference" member type because I cannot declare a
> pointer to a reference. Uncommenting the penultimate line of code
> will result in the compiler telling me just that. Fair enough and
> understood.
>
> My question is simply "how should I proceed"?
>[/color]

#include <iostream>
#include <ostream>
#include <vector>



typedef char One;
typedef struct { char a[2]; } Two;

/* Could do with a better name :)
*/
template < typename Valid > struct has
{
typedef One type;
};

/* These 4 function's have bodies just so the last line of main
compiles and run's (i.e for testing).
*/

template <typename T>
typename has< typename T::value_type >::type has_value_type( int )
{
return One();
}

template <typename T>
Two has_value_type(...)
{
return Two();
}

template <typename T>
typename has< typename T::reference >::type has_reference( int )
{
return One();
}

template <typename T>
Two has_reference(...)
{
return Two();
}


int main()
{
typedef std::vector<int> IntVec;

std::cout << "IntVec has value_type? "
<< (sizeof(has_value_type<IntVec>(0)) == 1)
<< std::endl;

std::cout << "IntVec has reference? "
<< (sizeof(has_reference<IntVec>(0)) == 1)
<< std::endl;

std::cout << "int has reference? "
<< (sizeof(has_reference< int >(0)) == 1)
<< std::endl;

has_value_type<IntVec>(0);
return 0;
}

HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Angus Leeming
Guest
 
Posts: n/a
#4: Jul 22 '05

re: Ascertaining whether T::reference exists.


tom_usenet wrote:[color=blue][color=green]
>>template <typename T>
>>One has_reference(typename T::reference const *);[/color][/color]
[color=blue]
> template <typename T>
> One has_reference(typename T::reference (*)());[/color]

Ahhhhhh. A pointer to a function returning a reference.

Thank you, Tom.

Angus

Angus Leeming
Guest
 
Posts: n/a
#5: Jul 22 '05

re: Ascertaining whether T::reference exists.


Rob Williscroft wrote:[color=blue]
> template < typename Valid > struct has { typedef One type; };
>
> template <typename T>
> typename has< typename T::reference >::type has_reference( int );
>
> template <typename T>
> Two has_reference(...);[/color]

The old chestnut of you can solve everything with an additional layer
of indirection.

Thanks, Rob.
Angus

Closed Thread