Ascertaining whether T::reference exists.

A

Angus Leeming

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;
}
 
T

tom_usenet

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"?
template <typename T>
One has_reference(typename T::reference const *);

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
 
R

Rob Williscroft

Angus Leeming wrote in
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"?

#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.
 
A

Angus Leeming

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

Ahhhhhh. A pointer to a function returning a reference.

Thank you, Tom.

Angus
 
A

Angus Leeming

Rob said:
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(...);

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

Thanks, Rob.
Angus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top