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

发布于 2024-12-08 17:07:06 字数 587 浏览 0 评论 0原文

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

尬尬 2024-12-15 17:07:06

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

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 };
};
方圜几里 2024-12-15 17:07:06

您不能在外部类定义中添加嵌套类的特化。不过,让内部特征类成为一个单独的实体会更简单,也更可重用:

#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 命名空间中。

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.

我的影子我的梦 2024-12-15 17:07:06

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

Move the function specialization outside of class and inside a .cpp file, it doesn't work with headers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文