【问题标题】:How to use enable_if as template parameter with specialization如何使用 enable_if 作为具有专业化的模板参数
【发布时间】:2016-04-13 12:15:31
【问题描述】:

为什么第二个函数不能匹配类定义中的模板??

    Class C {        
            template <typename T, typename T2 = T>
            T val() const;
        };

        template <>
        std::string C::val() const { 
             //OK
        }

        template <typename T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
        T C::val() const {
            //Not OK
        }

编辑: 这是我想要实现的目标的概述。基本上我正在编写一个函数来解析和返回基于模板类型的对象。我有一些自己定义的类,即我必须解析它们的成员。我还需要解析数字类型和字符串。所以我为我定义的每个类都写了一个专门的版本。解析为数字类型并返回给定类型的版本(当然我必须确保给定类型是数字,因此启用 if)

【问题讨论】:

  • 你在写c++?从未见过“Class”,不需要';'在类定义结束时?你能给我们一个sscce.org吗?
  • @Klaus 我为我的问题添加了一些描述。
  • @mkmostafa 看看 sfinae 机制

标签: c++ templates


【解决方案1】:

要使用 SFINAE,请在模板声明中使用它,而不是专门化:

class C {
    template <typename T, typename T2 = typename std::enable_if<std::is_arithmetic<T>::value>::type>
    T val() const;
};

如果您想区分算术类型和非算术类型(两者都允许),您可以使用标记:

class C {
public:
    struct arithmetic_tag {};
    struct non_arithmetic_tag {};

    template <typename T>
    T val(typename std::conditional<std::is_arithmetic<T>::value, arithmetic_tag, non_arithmetic_tag>::type tag = {}) const
    {
        return get_val<T>(tag);
    }

private:
    template <typename T>
    T get_val(C::non_arithmetic_tag) const;

    template <typename T>
    T get_val(C::arithmetic_tag) const;
};

或将专业化委托给辅助类:

class C {
public:
    template <typename T>
    T val() const
    {
        return ValGetter<T>::get(this);
    }

private:
    template <typename T, bool is_arithmetic = std::is_arithmetic<T>::value>
    struct ValGetter;
};

// Arithmetic
template <typename T>
struct C::ValGetter<T, true>
{
    static T get(C const* c);
};

// Non-arithmetic
template <typename T>
struct C::ValGetter<T, false>
{
    static T get(C const* c);
};

编辑:部分特化(bool 参数)不适用于方法,而是显示标记和辅助类

【讨论】:

  • 我想了解为什么它不能这样工作。我认为 enable_if 最终返回 T 的类型,因此它应该与当前定义一起使用
  • @mkmostafa 它不起作用,因为对于非算术类型,它没有定义 type 并且 SFINAE 不适用于专业化。
  • @StenSoft 这是一个特殊的结构/类专业化而不是一种方法,这是一个巨大的差异
  • 但我想区分算术、从特定基 (is_base_of) 继承的类和其他类。除了每次都必须添加这些布尔类型之外,还有其他优雅的解决方案吗?
  • @WojciechFrohmberg 哦,对。它需要标记。我会更新答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-12
  • 2018-06-06
相关资源
最近更新 更多