What is the cheapest way to specialize a feature item

I have a trait class that only needs to provide one information about the other types (as a string):

template<typename T>
struct some_traits {
    static const char* const some_string;
};

      

I need to provide special instances some_string

for each type. The usual way I know how to do this is to declare only some_traits

and then write specializations:

template<typename T>
struct some_traits;

template<>
struct some_traits<blah> {
    static const char* const some_string;
};
const char* const some_traits<blah>::some_string = "blah string";

      

It is, however, a lot of code when I only need specialized ones some_string

. Is there a way to simplify this?

I tried messing around with explicit specializations, but couldn't come up with a syntax that didn't make the compiler splash poisonous error messages on my face.

Notes:

  • I know I can hide this behind a macro. I'm still curious.
  • This is required to compile on an embedded platform with GCC 4.1. So C ++ 03 is all we have. (Boost is ok, but for limited Posix support, we're stuck with 1.52, if that matters.)
+3


source to share


2 answers


You can explicitly specialize elements of class templates:

template<typename T>
struct some_traits {
    static const char* const some_string;
};

template<>
char const* const some_traits<int>::some_string = "int";

      

This should reduce the overhead with minor announcements of new specializations. However, this method cannot be applied to partial specializations:

template<typename T> struct foo {};
template<typename T>
char const* const some_traits<foo<T>>::some_string = "foo<T>"; // error

      

... that is, unless you add partial specialization for some_traits

:

template<typename T>
struct some_traits<foo<T>> {
    char const* const some_string;
};

      


Two alternatives:

(1) Using ADL and functions



template<typename T> struct some_string_tag {};

template<typename T>
struct some_traits {
    static const char* const some_string;
};
template<typename T>
char const* const some_traits<T>::some_string = get_string(some_string_tag<T>());

      

The specialization can then be written as:

char const* get_string(some_string_tag<int>) { return "int"; }

      

And partial specializations like:

template<typename T>
char const* get_string(some_string_tag<foo<T>>) { return "foo<T>"; }

      

(In this case some_traits

, this is the point to customize how the string is found, and provides convenient access to the string as a variable.)

(2) Second trait using built-in function

template<typename T>
char const* const some_traits<T>::some_string = some_traits_X<T>::get_string();

template<typename T> struct some_traits_X {
    // provide: static char const* get_string();
};

template<>
struct some_traits_X<int> {
    static char const* get_string() { return "int"; }
};

template<typename T>
struct some_traits_X<foo<T>> {
    static char const* get_string() { return "foo<T>"; }
};

      

+7


source


Why not use functions?



template<typename T>
struct some_traits {
    static const char* const some_string();
};

template<>
struct some_traits<blah> {
     static const char* const some_string() { return "blah string"; }
};

      

-1


source







All Articles