【问题标题】:Specialized template method with derived classes as argument以派生类为参数的专用模板方法
【发布时间】:2012-01-12 15:16:19
【问题描述】:

对于特定类 A 专用的模板方法,有没有办法调用派生自 A 的类的专用代码?

最小的例子

#include <iostream<  

class A
{};

class B : public A
{};

class Templator
{
public :
    template <class T>
    void dance(T *argument);
};

template <class T>
void Templator::dance(T *argument)
{
    std::cout << "General implementation" << std::endl;
}

template<>
void Templator::dance<A> (A* )
{
    std::cout << "Specialized implementation" << std::endl;
}

int main()
{
    A a;
    B b;

    Templator tt;
    tt.dance(&a);
    tt.dance(&b);

    return 0;
}

对应输出

特殊实现
一般实现


换句话说,我希望这两个输出是:

专业化实现
专业化实现

【问题讨论】:

标签: c++ templates polymorphism


【解决方案1】:

在 C++11 中,您可以使用 std::enable_ifstd::is_base_and_derived

class Templator{
public :
    template <class T>
    typename std::enable_if<!std::is_base_and_derived<A, T>::value, void>::type 
    dance(T *argument) { 
       std::cout << "General implementation" << std::endl;
    }
    template <class T>
    typename std::enable_if<std::is_base_and_derived<A, T>::value, void>::type 
    dance(T *argument) { 
       std::cout << "Specialized implementation" << std::endl;
    }
};

您可以在 C++03 中使用 boost::enable_if_cboost::is_base_ofstd::tr1::is_base_of 并自己编写 enable_if 来做同样的事情(请参阅 here

【讨论】:

  • 谢谢,我接受了你的回答,因为它说明了 enable_if 和 is_base_of 的使用(我显然不知道存在)。它正在解决我的具体问题,这绝对是一个加分; )
  • 我正要建议您使用 disable_if&lt;P&gt; 而不是 enable_if&lt;!P&gt;,然后才意识到它不包含在 C++11 中(就像原来的 boost::enable_if 采用元函数而不是布尔值)... 但是,它们包含第二个参数的默认参数,因此如果您想避免混乱,可以省略 void
  • @LucTouraille:我个人更喜欢明确说明void,因为即使它是默认参数,我认为明确提及返回类型是使代码更清晰的好主意。
  • 当然,这是一个站得住脚的观点:)。我只是为OP的信息发表了此评论。
【解决方案2】:

您只需将&amp;b 转换为A*

如果您更改此代码

tt.dance(&a);
tt.dance(&b);

到此代码

tt.dance(&a);
tt.dance((A*)&b);

输出变成

Specialized implementation
Specialized implementation

【讨论】:

  • 是的,它可以工作(就像打电话给tt.dance&lt;A&gt;(&amp;b)),但很抱歉我把我的问题简单化了。我仍然需要将 T 解析为 B,因为在 T 是 A 或 B 的情况下,我的真实方法实现调用不同的代码......现在我用它来表达它,我明白我的要求是不可能的,因为我想让T成为B和A。那些问答网站也很适合自学^^
【解决方案3】:

这应该可以将boost::enable_ifboost::is_base_of 结合使用。

【讨论】:

  • 是的,它与纯粹的“专业化”不同,改为使用 SFINAE……但这是使其工作的一种方式(参见问题下的 Lol4t0 指针)
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 2014-12-10
  • 1970-01-01
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多