加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

指定类的基类的C模板参数的使用和缺点?

发布时间:2020-12-16 07:17:07 所属栏目:百科 来源:网络整理
导读:背景 最近我一直在考虑如何设计一个特定的软件,有一点我已经制作了下面这篇文章: template typename ... Mixinsclass Foo : public virtual Mixins... { /* ... */}; 我的想法是能够根据用户的需要使用其他属性或行为来扩充基类.假设一个应用程序需要使用带
背景

最近我一直在考虑如何设计一个特定的软件,有一点我已经制作了下面这篇文章:

template <typename ... Mixins>
class Foo : public virtual Mixins... {
    /* ... */
};

我的想法是能够根据用户的需要使用其他属性或行为来扩充基类.假设一个应用程序需要使用带有标识号的Foos.也许其他一些应用程序需要能够用颜色来谈论Foos.可以通过添加以下类来满足这些需求:

class HasID {
    int m_id = -1;

public:
    int getID() { return m_id; }
    void assignID(int id) { m_id = id; }
};

class HasColor {
public:
    int color = 0;
};

问题

我对这段代码的两个问题如下:

>使用这样的模板有什么用处和缺点?
>这个特定的模式有名字吗?

附加示例代码

这是另一个示例,展示了可以打印扩充类对象的详细信息.

打印功能:

// Default printBase
template <typename Base>
void printBase(std::ostream& out,Base& x) {}

// printBase for HasID
template <>
void printBase(std::ostream& out,HasID& x) {
    out << ",ID=" << x.getID();
}

// printBase for HasColor
template <>
void printBase(std::ostream& out,HasColor& x) {
    out << ",color=" << x.color;
}

// Recursive step of printBases
template <typename Derived,typename Base,typename ... Bases>
void printBases(std::ostream& out,Derived& x,Base& y) {
    printBase(out,y);
    printBases<Derived,Bases...>(out,x,x);
}

// Base case of printBases    
template <typename Derived>
void printBases(std::ostream& out,Derived& y) {}

// ostream operator
template <typename ... Mixins>
std::ostream& operator<<(std::ostream& out,Foo<Mixins...>& x) {
    out << "<Foo";
    printBases<Foo<Mixins...>,Mixins...>(out,x);
    return out << '>';
}

主要:

int main()
{
    Foo<> plainFoo;
    Foo<HasID> fooWithID;
    fooWithID.assignID(42);
    Foo<HasID,HasColor> multiTalentedFoo;
    multiTalentedFoo.assignID(1234);
    multiTalentedFoo.color = 0xff0000;

    std::cout
        << plainFoo << 'n'
        << fooWithID << 'n'
        << multiTalentedFoo << 'n';
}

输出:

<Foo>
<Foo,ID=42>
<Foo,ID=1234,color=16711680>

解决方法

My two questions about this code are as follows:

Does this particular pattern have a name?

What are the uses and drawbacks of using templates like this?

CRTP“奇怪地反复出现模板模式”或有时也称为“mixin”.

https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

我们真的想再次讨论这里的缺点,而网络知道这种模式/成语吗?讨论得足够多了:-)

https://softwareengineering.stackexchange.com/questions/123886/is-crtp-used-much-and-why-it-is-isnt

本文http://www.drdobbs.com/building-more-flexible-types-with-mixins/184402056注释:

The biggest drawback of the CRTP technique is that constructors aren’t inherited. This means that if you use an initializing constructor in your implementation class,every extension will have to have an appropriate initializing constructor. This causes the extensions to be more restricted and,as such,less useful.

这不再是真的,因为对于c 14,你有很好的机会用可变参数模板和基类的构造函数调用链来杀死那个参数.继承&委托构造者也将为此目的提供帮助.

与所有模板一样,您必须记住每个实例化都是一种新类型,可能会导致可执行文件中出现大量代码重复.我经常使用这种模式并接受成本.另一种方法是手工编写可执行大小不小的代码.你必须为你需要付出代价.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读