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 };
};
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 };
};
You cannot add specializations of nested classes inside the outer class definition. It'd be simpler, and more reusable, to make the inner trait class a separate entity, though:
#include <type_traits>
template <typename> struct has_variable_length; // intentionally undefined!
template <> struct has_variable_length<std::wstring> : std::true_type { };
template <> struct has_variable_length<int> : std::false_type { };
// ...
template <typename T> struct MyTraits
{
static const bool variable_length = has_variable_length<T>::value;
// ...
};
You could wrap the individual trait classes into a detail
namespace if you prefer.
Move the function specialization outside of class and inside a .cpp file, it doesn't work with headers.
精彩评论