1

我正在尝试使用“现代 C++ 设计”中的类型特征,使用模板来确定类型是否具有可变大小。例如,字符串需要可变大小的存储空间,而 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 };
};
4

3 回答 3

5

2003 C++ 标准只允许封闭类定义之外的成员模板特化。此外,超出定义的特化必须是封闭模板的显式完整特化。Microsoft 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 };
};
于 2011-10-09T22:22:15.810 回答
4

您不能在外部类定义中添加嵌套类的特化。但是,将内部 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;
  // ...
};

如果您愿意,可以将各个特征类包装到detail命名空间中。

于 2011-10-09T22:21:19.980 回答
0

将函数特化移到类之外和 .cpp 文件中,它不适用于标头。

于 2012-06-25T00:57:01.307 回答