可变参数成员函数参数包扩展

时间:2018-08-13 16:26:53

标签: c++ c++14 variadic-templates variadic-functions template-meta-programming

我需要帮助将可变参数成员函数添加到c ++ 14类以支持日志记录。我的班级当前正在Windows和另一个无法访问标准库的嵌入式操作系统上运行。我的代码中散布着数百个预处理器oauth,如下所示,我的目标是将这些块(其中许多具有多个参数)整合为一个通用的可变成员函数,可以登录到{{1} }通过#ifdefs(_WIN32)或替代地(Embedded OS)到特殊的boost::log对象,该对象支持像一些非常基本的类型(包括boost::format)一样的流插入。将后一个对象视为类似于gErrorLineLog的对象。

const char*

以下堆栈溢出答案boost::format with variadic template arguments对于回答如何将Windows / std::stringstream面放入可变参数成员函数大有帮助,但是我不知道如何循环扩展包装嵌入式案例(在我的可变参数模板函数中,我必须按照以下几行做一些事情:

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

编辑

到目前为止,对于嵌入式案例(我没有STL,因此没有boost::format),我有一个部分解决方案-感谢max66提供的替代技巧在我将记录器及其相关的可变参数传递给我时效果很好争论。

看完Jason Turner的C ++每周视频episode 4之后,他讲解了大约70%的内容,解释了与c ++ 14兼容的参数包扩展背后的一些神秘魔术。我本来希望使用折叠表达式(再次感谢max66提供更紧凑的折叠表达式语法),但是不幸的是,gcc 5.3.0并不c ++ 17,因此不使用折叠表达式。

反馈后我的最新版本如下:

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

然后在我的应用程序代码中将其称为:

std::initializer_list<int>

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

1 个答案:

答案 0 :(得分:2)

不知道您到底想要什么,但是...我想是这样的(警告:未经测试的代码)

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), ... ); }