【问题标题】:Simplifying work with variadic functions / macros使用可变参数函数/宏简化工作
【发布时间】:2016-10-18 15:01:41
【问题描述】:

我正在写一堆这样的函数:

template <>
Error SyntaxError<unfinished_string>(unsigned int line) {
    std::stringstream message;
    message << "SyntaxError: unfinished string (starting at line " << line << ").";
    return Error(Error::Type::syntax, message.str());
}

template <>
Error SyntaxError<malformed_number>(std::string number, unsigned int line) {
    std::stringstream message;
    message << "SyntaxError: malformed number (" << number << ") at line " << line << '.';
    return Error(Error::Type::Syntax, message.str());
}

...

拥有一个看起来像这样的可变参数函数/宏也不错:

Error proto(/*variable number & type of arguments*/) {
    std::stringstream message;
    message << "SyntaxError: " << /*arguments passed, separated by <<s */;
    return Error(Error::Type::syntax, message.str());
}

这样我就可以把我的函数写成:

template <>
Error SyntaxError<unfinished_string>(unsigned int line) {
    return proto("unfinished string (starting at line ", line, ").");
}

template <>
Error SyntaxError<malformed_number>(std::string number, unsigned int line) {
    return proto("malformed number (", number, ") at line ", line, '.');
}

这有可能吗?如果是怎么办?

【问题讨论】:

  • 不知道为什么人们投票关闭。答案是肯定的。我会在一秒钟内整理出一个真正的答案。
  • 您需要多少个版本?可以向Error 添加更多构造函数吗?就像std::system_error 一样。

标签: c++ c++11 variadic-functions variadic-macros


【解决方案1】:

如果您想转换参数的可变参数列表并将它们完全流式传输,那么您可以实现一个附加函数,将每个参数递归地附加到该流。 示例:

template< typename FirstArg, typename... Args >
inline std::ostream& join_args( std::ostream& os, FirstArg arg, Args... args ) {
   os << arg;
   return join_args( os, args... );
}

一步一步,你将耗尽争论。注意你处理它的顺序,( std::ostream&amp; os, FirstArg arg, Args... args )( std::ostream&amp; os, Args... args, LastArg arg ) 不一样。

最后但并非最不重要的一点是,您应该涵盖极端情况(一个或没有参数,取决于您的问题):

inline std::ostream& join_args( std::ostream& os ) {
   return os;
}

不用担心递归效率,编译器将能够内联所有函数调用(因为它在编译时知道递归的深度)并将所有代码展平,这样生成的程序就会更多或不如手动将所有参数附加到单个流中。

【讨论】:

  • return join_args( args... ); 不应该将os 作为第一个参数传递(即join_args(os, args...))吗?
  • 肯定是 user6245072,我只是草稿编码,忘记查看这些错误。谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多