Re: SFINAE, specialization, trait selection and problems
Bjorn Fahller wrote:
I think I may have gone over board on this one, but I have a template, for
which I can provide good default behaviour for all built in integer types,
and for random accessible containers of built in integer types, and
especially so for strings.
So, below is a nasty piece of code showing the thoughts for this. I'm sure
it's possible to get the functionality in more elegant ways. The code works
with G++ 4.1.1 and Intel C++ 9.1, although I had to resort to an #ifdef due
to different ideas between the two. Comeau online is very unhappy about the
whole thing and complains violently (it strongly disagrees with the
T::iterator thing.)
Which is right, if any? What's a better way of achieving the same thing?
Sorry for the longish code, but I have problems making a shorter example.
I think it should possible to simply your implementation. First, take
advantage of std::tr1::type_traits (soon-to-be, std::type_traits) for
the integral type test. Second, specialize the is_string test for
std::string and std::wstring (any other string type can add their own
specialization). Third, use a simplified SFINAE test for the
"randomly-accessbile container of integral types":
Applying these suggestions produces the following implementation:
#include <string>
#include <iostream>
#include <limits>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <iterator>
#include <tr1/type_traits>
#include <boost/static_assert.hpp>
using std::tr1::is_integral;
template <class T>
struct is_string
{
static const bool value = false;
};
template <>
struct is_string< std::string >
{
static const bool value = true;
};
template <>
struct is_string< std::wstring >
{
static const bool value = true;
};
template <class T1, class T2 = std::random_access_iterator_tag>
struct is_random_access_container_of_ints
{
static const bool value = false;
};
template <class T>
struct is_random_access_container_of_ints<
T,
typename T::iterator::iterator_category >
{
static
const bool value = is_integral<typename T::value_type>::value;
};
template <class T>
void Check()
{
BOOST_STATIC_ASSERT(
is_integral< T >::value or
is_string< T >::value or
is_random_access_container_of_ints< T >::value);
}
#define CHECK(t) Check<t>()
int main()
{
// These should all work:
CHECK( int );
CHECK( std::vector<int> );
CHECK( std::wstring );
CHECK( std::deque<int> );
CHECK( std::string );
// These must cause compilation errors if uncommented:
// CHECK( std::vector< std::string > );
// CHECK( std::list<int> );
// CHECK( double );
// CHECK( name );
}
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]