使用可变函数/宏简化工作
Simplifying work with variadic functions / macros
我正在写一堆这样的函数:
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, '.');
}
这有可能吗?如果是怎么办?
如果你想转换可变参数列表并将它们一起流式传输,那么你可以实现一个附加函数,以递归方式将每个参数附加到该流。
示例:
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& os, FirstArg arg, Args... args )
与 ( std::ostream& os, Args... args, LastArg arg )
不同。
最后但同样重要的是,您应该涵盖极端情况(有或没有参数,具体取决于您的问题):
inline std::ostream& join_args( std::ostream& os ) {
return os;
}
不用担心递归效率,编译器将能够内联所有函数调用(因为它在编译时知道递归有多深)并展平所有代码,这样生成的程序将是或多或少相当于手动将所有参数附加到单个流中。
我正在写一堆这样的函数:
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, '.');
}
这有可能吗?如果是怎么办?
如果你想转换可变参数列表并将它们一起流式传输,那么你可以实现一个附加函数,以递归方式将每个参数附加到该流。 示例:
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& os, FirstArg arg, Args... args )
与 ( std::ostream& os, Args... args, LastArg arg )
不同。
最后但同样重要的是,您应该涵盖极端情况(有或没有参数,具体取决于您的问题):
inline std::ostream& join_args( std::ostream& os ) {
return os;
}
不用担心递归效率,编译器将能够内联所有函数调用(因为它在编译时知道递归有多深)并展平所有代码,这样生成的程序将是或多或少相当于手动将所有参数附加到单个流中。