gpt4 book ai didi

C++ 创建一个具有可变模板方法的接口(interface)

转载 作者:行者123 更新时间:2023-11-30 02:14:50 24 4
gpt4 key购买 nike

所以基本上我正在寻找一种方法来为不同平台创建具有各种实现的接口(interface)。通常这会很简单,但我想为记录器创建一个接口(interface),并且能够具有如下功能是我的目标:

class Log {
public:
template<typename ...Args>
virtual void log(const char* fmt, const Args&... args) const = 0;

template<typename ...Args>
virtual void warn(const char* fmt, const Args&... args) const = 0;

template<typename ...Args>
virtual void error(const char* fmt, const Args&... args) const = 0;
};

现在显然这行不通,因为您不能拥有纯虚拟模板函数。

我看到的一种方法是使 Log 类成为 CRTP(奇怪的重复模板模式)类,并使用类似于以下内容的方法来获得所需的行为:

//Log.h (template<typename T> class Log {...})
template<typename ...Args>
void log(const char* fmt, const Args&... args) const {
//the following line would essentially downcast the 'this' pointer and
//call it's version of log instead...
reinterpret_cast<T*>(this)->log(fmt, args...);
}

//ExampleLog.h (class ExampleLog : public Log<ExampleLog> {...})
template<typename ...Args>
void log(const char* fmt, const Args&... args) const {
m_logger->log(fmt, args...);
}

缺点是这会使界面难以使用,经常需要使用 Log<Impl> Impl在哪里(实现)可能不为人所知/公开。

我真的不知道如何创建一个包含具有可变数量和类型参数的函数的接口(interface)......?

最佳答案

无论您有错误、警告还是其他内容,都归结为一个记录的文本字符串。您的虚函数只需要将单个 std::string 作为参数,Log 基类中的所有这些函数将负责将参数格式化为单个 std::string 然后调用真正的虚函数:

class Log {
public:
template<typename ...Args>
void log(const char* fmt, Args && ...args) const
{
do_log(do_format(std::forward<Args>(args)...));
}

template<typename ...Args>
void warn(const char* fmt, Args && ...args) const
{
do_warn(do_format(std::forward<Args>(args)...));
}

template<typename ...Args>
void error(const char* fmt, Args && ...args) const
{
do_error(do_format(std::forward<Args>(args)...));
}

private:

template<typename ...Args>
inline std::string do_format(const char *fmt, Args && ...args)
{
// Your homework assignment goes here
}

virtual void do_log(const std::string &) const = 0;

virtual void do_warn(const std::string &) const = 0;

virtual void do_error(const std::string &) const = 0;
};

现在剩下要做的就是实现 do_format()。无论如何,这是您在日志记录类中必须做的事情,但需要在这里完成,有效地类型删除所有模板参数并将它们替换为单个 std::string。如果您的日志记录功能归结为记录 std::string 以外的内容,那么在这里构造它,这就是被扔进您的虚函数的内容。

至于为什么你的可变参数模板参数应该使用 && 而不是 const & 的原因,这个主题在其他地方被相当广泛地涵盖,主题被称为 "perfect forwarding" ,因此,我建议您引用那些众多的 stackoverflow 和 Google 搜索结果以了解更多详细信息。

此外,正如其他地方广泛介绍的那样,您必须 declare and define do_format() inline 。这将导致明显的代码膨胀。有多种减少代码膨胀的技术,但这又是另一个讨论主题。

关于C++ 创建一个具有可变模板方法的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57124101/

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