gpt4 book ai didi

c++ - Curiously Recurring Template Pattern (CRTP) 是正确的解决方案吗?

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

场景

考虑一个 Logger 类,它有一个为标准 C++ 类型重载的成员函数 write(),还有一些方便的函数模板,比如 writeLine() 内部调用 write():

class Logger {
public:
void write(int x) { ... }
void write(double x) { ... }
...

template <typename T>
void writeLine(T x) { write(x); ... }
...
};

进一步考虑一个子类 FooLogger,它为特定于域的类型添加了额外的 write() 重载(我们称其中两个为 FooType1FooType2):

class FooLogger : public Logger {
public:
using Logger::write;

void write(FooType1 x) { ... }
void write(FooType2 x) { ... }
...
};

( self-contained example program at Ideone )

问题

FooLogger::write(),当直接调用时,现在支持两个类中任一个提供重载的任何参数。

但是,FooLogger::writeLine() 仅支持类 Logger 具有 write() 重载的参数类型...它没有看到在类 FooLogger 中声明的附加 write() 重载。

不过,我希望它能看到它们,这样它也可以用这些参数类型来调用!

当前解决方案

我使用 Curiously Recurring Template Pattern (CRTP) 让它工作:

template <typename TDerivedClass>
class AbstractLogger {
...

template <typename T>
void writeLine(T x) { static_cast<TDerivedClass*>(this)->write(x); ... }
};

class Logger : AbstractLogger {}


class FooLogger : public AbstractLogger<FooLogger> {
...
};

( self-contained example program at Ideone )

虽然它完成了工作,但它是以增加代码复杂性和冗长为代价的:

  1. 它使基类的实现明显更难阅读(参见 Ideone 链接),也更难维护(在将更多代码添加到以后的类(class)!)
  2. 它需要将AbstractLoggerLogger 分成两个类。
  3. 因为基类现在是一个类模板,所以它的所有成员函数的实现现在都必须包含在 header 中(而不是 .cpp 文件)——即使是那些没有的需要做 static_cast 事情。

问题

考虑到上述情况,我正在寻求具有 C++ 经验的人的见解:

  • CRTP 是这项工作的正确工具吗?
  • 还有其他方法可以解决这个问题吗?

最佳答案

换个方式怎么样:

template <typename ...Ts>
class Logger : private Ts...
{
public:
using Ts::write...;

void write(int x) { /*...*/ }
void write(double x) { /*...*/ }
// ...

template <typename T>
void writeLine(T x) { write(x); /*...*/ }
// ...
};

class FooWriter
{
public:
void write(FooType1 x) { /*...*/ }
void write(FooType2 x) { /*...*/ }
};
using FooLogger = Logger<FooWriter>;

然后使用任何(或它们的别名):

Logger<>Logger<FooWriter>Logger<FooWriter, BarWriter> ...

关于c++ - Curiously Recurring Template Pattern (CRTP) 是正确的解决方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54119501/

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