gpt4 book ai didi

c++ - 指定类基类的 C++ 模板参数的用途和缺点?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:15:43 29 4
gpt4 key购买 nike

背景

最近我一直在考虑如何设计一个特定的软件,有一次我制作了以下部分:

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

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

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

问题

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

  1. 使用这样的模板有什么用处和缺点?
  2. 这个特殊的图案有名字吗?

附加示例代码

这是一个额外的示例,展示了打印增强类对象的详细信息的可能性。

打印函数:

// 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& x, Derived& y) {}

// ostream operator
template <typename ... Mixins>
std::ostream& operator<<(std::ostream& out, Foo<Mixins...>& x) {
out << "<Foo";
printBases<Foo<Mixins...>, Mixins...>(out, x, 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 来说,这不再是正确的,你有很好的机会用可变参数模板和基类的构造函数调用链来消除这个论点。继承和委派构造函数也有助于实现这一目的。

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

关于c++ - 指定类基类的 C++ 模板参数的用途和缺点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38605329/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com