【问题标题】:Specializing a class template method for derived classes为派生类专门化一个类模板方法
【发布时间】:2012-02-23 12:38:58
【问题描述】:

对于共享公共基类的类的以下代码段中的 doIt() 方法,我很感激帮助,如下所示

#include <iostream>
#include <boost/utility.hpp>
#include <boost/type_traits.hpp>

struct BarBase {};
struct Bar: BarBase {};

struct FooBase {};
struct Foo: FooBase {};

template <typename T>
struct Task
{
    // I'd like to specialize this method for classes with a common base class
    void doIt();        
};

// my attempt (does not compile)
template <typename T>
typename boost::enable_if<boost::is_base_of<FooBase, T> >::value
doIt() {
    std::cout << "Type is derived from FooBase\n";
}


int main()
{
    Task<Foo> f;
    f.doIt();
}

【问题讨论】:

  • 我认为你不能专门化类模板成员函数,你必须专门化类。

标签: c++ templates sfinae


【解决方案1】:

您不能专门化模板类成员。你可以特化一个类,每个特化都是一个完全独立的类,它不继承非特化模板的任何内容(它可能有也可能没有非特化类的全部或部分成员)。

您还可以做的是在模板类中拥有一个模板成员函数,并对其进行专门化。所以你可以这样做:

template <typename T>
struct Task
{
    void doIt() { doItPriv<T>(); }
private:
    template<typename T1>
    void doItPriv();  
};

然后专门化doItPriv

【讨论】:

    【解决方案2】:

    根据this的回答,

    SFINAE 仅在模板的参数推导中进行替换时才有效 论据使构造不正确。

    这就是为什么你不能那样做:

    template <typename T>
    struct Task
    {
        typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt() {
            std::cout << "Type is derived from FooBase\n";
        }   
    
        typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt()
        {
        }
    };
    

    这里doIt() 不是模板,所以没有任何推论。 但您可以执行以下操作:

    template <typename T1>
    struct Task
    {
        template <typename T>
        typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt_() {
            std::cout << "Type is derived from FooBase\n";
        }   
    
        template <typename T>
        typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt_()
        {
        }
    
        void doIt()
        {
            doIt_<T1>();
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2016-04-06
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多