Search code examples
c++templatesicc

Type Traits - Explicit template specialization. fails on xcode


I'm trying to use type traits like in "Modern C++ Design" using a template to determine if a type has a variable size or not. e.g. a string requires variable size storage, an int has fixed-size storage. This code works on Microsoft C++, now I'm porting to mac and I get the error:

explicit specialization is not allowed in the current scope

What's the correct way to specialize this?

template <typename T>
class MyTypeTraits
{
    template<class U> struct VariableLengthStorageTraits
    {
        enum { result = false };
    };
    template<> struct VariableLengthStorageTraits<std::wstring>
    {
        enum { result = true };
    };

public:
    enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
};

Solution

  • The 2003 C++ standard only allows member template specialization outside of the enclosing class definition. Also, the out-of-definition specialization must be an explicit full specialization of the enclosing template. Microsoft C++ is non-standard in this regard. The fix is simple, just move the inner template out of the enclosing template, since the inner template doesn't need its enclosing class template arguments:

    template<class U> struct VariableLengthStorageTraits
    {
        enum { result = false };
    };
    
    template<>
    struct VariableLengthStorageTraits<std::wstring>
    {
        enum { result = true };
    };
    
    template <typename T>
    struct MyTypeTraits
    {
        enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
    };