|
Boost : |
From: Beman Dawes (beman_at_[hidden])
Date: 1999-11-22 13:48:58
As part of an empty member optimization, Steve Cleary used a traits
class he called "constructor_parameter" to allow a constructor
parameter to be defined as "const T&" or plain "T&" according to the
template argument type.
Dietmar Kühl is working on a somewhat similar traits class called
"reference_traits" to solve a standard library problem with
std::make_pair( "abc", x ).
Steve's traits class specialized only references. It could also be
specialized for pointers and other built-in types.
It seems like this technique may have enough uses to make it a
candidate for boost/utility.hpp.
The following program can be used to experiment with the technique.
The output from CodeWarrior is:
typeid(i).name() is int
Constructing int which contains 1 via non-specialized template
Constructing int which contains 1 via T& specialization
Constructing int which contains 2 via T& specialization
Constructing int * which contains 0x0012ff64 via T* specialization
Constructing const int * which contains 0x0012ff64 via T*
specialization
Constructing long which contains 2 via long specialization
--Beman
----- snip here -----
// explore the parameter_traits idiom
#include <iostream>
#include <typeinfo>
using namespace std;
template< typename T >
struct parameter_traits
{
typedef T template_type;
typedef T raw_type;
typedef T const & parameter_type;
static const char * which() { return "non-specialized template";
}
};
template< typename T >
struct parameter_traits< T* >
{
typedef T * template_type;
typedef T raw_type;
typedef T * parameter_type;
static const char * which() { return "T* specialization"; }
};
template< typename T >
struct parameter_traits< T& >
{
typedef T & template_type;
typedef T raw_type;
typedef T & parameter_type;
static const char * which() { return "T& specialization"; }
};
template<>
struct parameter_traits< long >
{
typedef long template_type;
typedef long raw_type;
typedef long parameter_type;
static const char * which() { return "long specialization"; }
};
// could specialize for all the built-in types.
// usage example:
template< typename T >
struct single
{
T value;
single( typename parameter_traits<T>::parameter_type v ) :
value(v)
{
cout << "Constructing " << typeid(value).name()
<< " which contains " << value
<< " via " << parameter_traits<T>::which()
<< endl;
}
virtual ~single(){}
};
int main()
{
int i = 1;
cout << "typeid(i).name() is " << typeid(i).name() << endl;
single<int> x(i);
single<int&> y(i);
y.value = 2;
single<const int&> cy(i);
// cy.value = 3; // error: assign to constant
single<int*> z(&i);
single<const int*> cz(&i);
// cz.value = 4; // error: assign to constant
single<long> lx(i);
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk