Template partial specialization for multiple types overriding member function

只谈情不闲聊 提交于 2020-01-07 02:12:07

问题


I have class member functions defined as follows, providing a specification for one of them and letting the user provide their own specification for others:

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) {
    ...
}

Now, I'd like to provide a specialization for the function that will work for integral pair types. I have a template metafunction checking for integral pairs defined as follows:

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

Is it possible for me to provide my own specialization such that it works for all integer pairs, perhaps using the template metafunction I defined above?


回答1:


Its a bit of a contrived example and somewhat difficult to make sense of as-is. However, with a basic change its quite easy to add what you require. First its important to note that what you're defining above are not partial specialisations of bar (that would be impossible as you cannot partially specialize a function) but rather overloads. Next, you have a contrived system whereby you have an Enable parameter that has nothing to do with the function parameter - is this really your intention? If you made the change that the template parameter of the function is the same type as its variable parameter, the problem becomes straightforward - you add another overload for integral pairs, again using SFINAE to help you. Here is an example way of achieving what you need:

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


来源:https://stackoverflow.com/questions/38098372/template-partial-specialization-for-multiple-types-overriding-member-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!