可变参数函数参数包扩展



我需要帮助将可变参数成员函数添加到 c++14 类以支持日志记录。 我的类当前在两个窗口和另一个无法访问标准库的嵌入式操作系统上运行。 我的代码中散布着数百个预处理器#ifdefs如下所示,我的目标是将这些块(其中许多具有多个参数(合并到一个通用的可变参数成员函数中,我可以通过boost::format(_WIN32(或替代(嵌入式操作系统(登录到boost::log一个特殊的gErrorLineLog对象,该对象支持一些非常基本的类型(包括const char*(的流插入等运算符。 将后一个对象视为类似于std::stringstream的东西。

#if defined (_WIN32)
LOG_ERROR(gLogger, gChannel) << boost::format("%1%")
% "'Transmit429Request' invalid message length";
#else
gErrorLineLog << "error: TX429 [bad message length]";
#endif

以下带有可变参数模板参数的堆栈溢出答案 boost::format 在回答如何将 windows/boost::format侧放入可变参数成员函数方面大有帮助,但我不知道如何循环嵌入式案例的扩展包(我必须在我的可变参数模板函数中按照以下行做一些事情:

for (auto next : parameterpack) {
gErrorLineLog << next:
}

编辑

到目前为止,我有一个针对嵌入式情况的部分解决方案(我没有 STL,因此std::initializer_list<int>( - 感谢 max66 的替代技巧,当我传入带有相关可变参数的记录器时效果很好。

在看了 Jason Turner 的每周 C++ 视频第 4 集大约 70% 后,他解释了与 c++14 兼容的参数包扩展背后的一些神秘魔力。 我本来更喜欢使用折叠表达式(再次感谢 max66 提供替代更紧凑的折叠表达式语法(,但不幸的是 gcc 5.3.0 没有 c++17,因此折叠表达式(。

反馈后的最新版本如下:

template <typename LOGGER, typename ... Args>
void addLogEntry(LOGGER& VideoLogger, Args const& ... args)
{
#if defined (_WIN32)
LOG_INFO(gLogger, gChannel) << boost::format(
"DOUTRequest: query, eotw[0x%1%]")
% boost::io::group(std::setfill('0'),
std::hex, std::setw(4), *endOfFrame);
#else
// https://www.youtube.com/watch?v=VXi0AOQ0PF0
// parameter pack expansion using comma operator
VideoLogger.clear();
using unused = int[];
(void)unused{0, (VideoLogger << args, 0)...};
#endif
}

我在我的应用程序代码中调用它:

#if defined (_WIN32)
// I'm not sure how to get this right
LOG_INFO(gLogger, gChannel) << boost::format("received: TX429 with [%1%] labels") % numArincWords % 
#else  // THIS WORKS
addLogEntry(gReceiveLineLog,
"received: TX429 with [", dec,
numArincWords, "] labels");
#endif

如您所见,我还没有完全弄清楚如何在记录器或对记录器的调用中执行 win32 boost 操作。

不确定你到底想要什么,但是...我想是这样的东西(注意:代码未测试(

template <typename ELLT, typename ... Args>
void errorLog (ELLT & gErrorLineLog, Args const & ... as)
{
using unused = int[];
(void)unused { 0, ((void)gErrorLineLog << as, 0)... };
}

如果你可以使用C++17,也许只是

template <typename ELLT, typename ... Args>
void errorLog (ELLT & gErrorLineLog, Args const & ... as)
{ ( ((void)gErrorLineLog << as), ... ); }

相关内容

  • 没有找到相关文章

最新更新