使varargs Exception构造函数填充stringstream

Tom*_*ica 4 c++ templates stringstream

基本上我正在制作Exception类,我希望能够轻松传递调试细节,例如:

var error = someFunction();
if(error!=0) {
    throw MyException("someFunction ended with error state #",error,'.');
}
Run Code Online (Sandbox Code Playgroud)

这将要求MyException类接受可以处理的varargs参数stringstream.我不知道我究竟能做到这一点,我想象的是:

#include <string>
#include <sstream>
template /* MUCH DEEP MAGIC HERE**/
MyException::MyException(/* MOAR DEEP MAGIC!!! **/) {
    std::stringstream ss;
    for(/** ITERATE THROUGH MORE MAGIC**/) {
        ss<</**FETCH MAGIC STUFF**/;
    }
    this->message = ss.str();
}
Run Code Online (Sandbox Code Playgroud)

Cap*_*ous 9

扩展参数包时,可以滥用逗号运算符来执行此操作.这就是魔术.

template<typename Stream, typename ...Args>
Stream& print(Stream& o, const Args&... args)
{
    auto x = { ((o << args), 0)... };
    return o;
}
Run Code Online (Sandbox Code Playgroud)

这将一次一个地发送到流中的所有参数,同时在逗号构造初始化整数列表之后获取表达式的结果.

  • 更进一步解释`auto x`行:`x`是`std :: initializer_list <int>`.支撑初始化列表是扩展参数包的允许上下文; 表达式`{(foo args bar)...}`求值为`{(foo arg1 bar),(foo arg2 bar),(foo arg3 bar)}`.这在这里很有用,因为可以保证初始化列表中的项目从左到右进行计算,因此项目按正确的顺序发送到"o".将表达式的类型从`istream&`转换为`int`需要`,0`,因为初始化列表不能包含引用. (2认同)