【问题标题】:Template partial specialization for multiple types overriding member function覆盖成员函数的多种类型的模板部分特化
【发布时间】:2016-06-29 11:34:29
【问题描述】:

我有如下定义的类成员函数,为其中一个提供规范,并让用户为其他人提供自己的规范:

template <typename T>
class Foo {
    // specialization provided for integral types
    template <typename Enable = T>
    typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
        bar(const T& value);

    // provide your own specialization for other types
    template <typename Enable = T>
    typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
        bar(const T& value);
};

template <typename T>
template <typename Enable>
typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
    Foo<T>::bar(const T& value) {
    ...
}

现在,我想为适用于整对类型的函数提供一个特化。我有一个模板元函数检查定义如下的整数对:

template <typename T>
struct is_integral_pair : std::false_type {}; 

template <typename T1, typename T2> 
struct is_integral_pair<std::pair<T1, T2>> {
    static const bool value =
        std::is_integral<T1>::value && std::is_integral<T2>::value;
};

我是否可以提供我自己的特化,使其适用于所有整数对,也许使用我上面定义的模板元函数?

【问题讨论】:

    标签: c++ c++11 template-meta-programming


    【解决方案1】:

    这是一个人为的例子,而且有点难以按原样理解。但是,通过基本更改,很容易添加您需要的内容。首先需要注意的是,您在上面定义的不是bar 的部分特化(这是不可能的,因为您不能部分特化一个函数),而是重载。接下来,您有一个人为的系统,其中您有一个与函数参数无关的Enable 参数 - 这真的是您的意图吗?如果您更改了函数的模板参数与其可变参数的类型相同,那么问题就变得简单了——您为整数对添加了另一个重载,再次使用 SFINAE 来帮助您。这是实现您需要的示例方法:

    #include <iostream>
    
    template <typename T>
    class Foo {
    public:
    
        // specialization provided for integral types
        template <typename Enable>
        typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
            bar(const Enable& value);
    
        // provide your own specialization for other types
        template <typename Enable>
        typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
            bar(const Enable& value);
    
        // provide your own specialization for integral pairs 
        template <typename U, typename V>
        typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type
            bar(const std::pair<U,V>& value);
    
    };
    
    template <typename T>
    template <typename Enable>
    typename std::enable_if<std::is_integral<Enable>::value, size_t>::type
        Foo<T>::bar(const Enable& value) 
    {
        std::cout << "Integral" << std::endl;
        return 0;
    }
    
    template <typename T>
    template <typename Enable>
    typename std::enable_if<!std::is_integral<Enable>::value, size_t>::type
        Foo<T>::bar(const Enable& value) 
    {
        std::cout << "Non-Integral" << std::endl;
        return 0;
    }
    
    template <typename T>
    template <typename U, typename V>
    typename std::enable_if<std::is_integral<U>::value && std::is_integral<V>::value, size_t>::type
        Foo<T>::bar(const std::pair<U,V>& value) 
    {
        std::cout << "Integral pair" << std::endl;
        return 0;
    }
    
    int main()
    {
        Foo<int> foo;
    
        foo.bar(1);              //output "Integral"
        foo.bar(1.0);            //output "Non-Integral"
    
        foo.bar(std::pair<float, int>(1.0, 1));    //output "Non-integral"
        foo.bar(std::pair<long, int>(1, 1));       //output "Integral pair"
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-20
      • 2019-02-10
      • 1970-01-01
      • 2012-12-15
      • 2011-07-03
      • 1970-01-01
      • 2012-04-11
      • 1970-01-01
      相关资源
      最近更新 更多