类型特征-显式模板专门化.在xcode上失败

Type Traits - Explicit template specialization. fails on xcode

本文关键字:专门化 xcode 失败 特征 类型      更新时间:2023-10-16

我试图使用类型特征,如"现代c++设计"使用模板来确定类型是否具有可变大小。例如,string类型需要可变大小的存储空间,int类型需要固定大小的存储空间。这段代码在Microsoft c++上工作,现在我移植到mac上,我得到错误:

显式专门化在当前作用域中是不允许的

专门化这个的正确方法是什么?

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 };
};

2003年的c++标准只允许在封闭类定义之外的成员模板特化。此外,定义外的专门化必须是封闭模板的显式完全专门化。微软c++在这方面是非标准的。修复方法很简单,只需将内部模板移出封闭模板,因为内部模板不需要其封闭类模板参数:

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 };
};

不能在外部类定义中添加嵌套类的专门化。不过,让内部trait类成为一个单独的实体会更简单,也更容易重用:

#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;
  // ...
};

如果你愿意,你可以把单个的trait类包装成一个detail命名空间。

将函数专门化移出类并放入.cpp文件中,它不适用于头文件