具有继承的C ++模板部分专业化 [英] C++ template partial specialization with inheritance

查看:56
本文介绍了具有继承的C ++模板部分专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要struct的部分专业化,但我也想使用一些通用功能.例如,假设我有下一个类型:

I need partial specialization of the struct, but I'd like also use some common functionality. For example, suppose I have the next type:

template <typename A, typename B>
struct Foo  
{
    Foo& func0() { /* common actions with A and B */; return *this; }  
    void func1() { /* common actions with A and B */ }
    void func2() { /* common actions with A and B */ }
}

然后我想将其专门用于模板参数之一-例如,我想考虑Bint时的特殊情况,并且我想保留func0func1行为与常见的Foo(或者func0()必须为int返回我专用的Foo&),func2我要重写(假设我对整数有更有效的实现),并且我也想添加func3()仅适用于我的专业Foo.

Then I want specialize it for one of the template parameters - for example, I want consider special case when B is int, and I want to preserve func0 and func1 behaviour exactly the same as in common Foo (or course, func0() must return my specialized Foo& for int), func2 I want rewrite (suppose that I have more efficient implementation of it for integers), and I also want add func3() only for my specialized Foo.

当然,我可以简单地编写以下内容:

Of course, I can simpy write the following:

template <typename A>
struct Foo<A, int>  
{
    Foo& func0() { /* common actions with A and B */; return *this; }  
    void func1() { /* common actions with A and B */ }
    void func2() { /* actions with A and 'int' */ }
    void func3() { /* actions with A and 'int' */ }
}

但我想避免在func0func1中复制粘贴.

but I'd like to avoid copy-paste in func0 and func1.

我也可以将常见的Foo重命名为FooBase之类的内容,并从中继承Foo,但是在这种情况下,我不能将常见的情况用作

I also can rename common Foo to something like FooBase and simply inherit Foo from it, but in this case I can't use the common case as

Foo<float, float> a;

有什么方法可以让我同时使用

What methods does exist for allow me using both

Foo<float, float> a;

Foo<float, int> b;

是否没有复制和粘贴通用的Foo代码到专业化领域?

without copying and pasting common Foo's code to specialization?

我对c ++ 11和更早的标准兼容性都感兴趣.

I'm interested in both c++11 and earlier standard compatibility.

推荐答案

这似乎对我有用.

template <typename A, typename B>
struct Foo;

template <typename A, typename B>
struct FooBase
{
    Foo<A, B>& func0()
    {
        cout << "FooBase:func0\n";
        return static_cast<Foo<A, B>&>(*this);
    }

    void func1() { cout << "FooBase::func1\n"; }
    void func2() { cout << "FooBase::func2\n"; }
};

template <typename A, typename B>
struct Foo : public FooBase<A, B> {
};

template <typename A>
struct Foo<A, int> : public FooBase<A, int>
{
    void func2() { cout << "Foo<A, int>::func2\n"; }
    void func3() { cout << "Foo<A, int>::func3\n"; }
};

如果最终需要在FooBase中定义Foo,则可能需要使用CRTP技巧,将派生类作为模板参数传递给FooBase,但是对于简单的事情,我认为前向声明就足够了.

If you wind up needing the definition of Foo within FooBase, you may need to use the CRTP trick of passing the derived class as a template parameter to FooBase, but for simple things I think the forward declaration is sufficient.

这篇关于具有继承的C ++模板部分专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆