我可以在没有流对象的情况下调用流操作符重载吗?

时间:2015-05-07 22:42:30

标签: c++

假设我希望throw包含一个包含某些对象信息的字符串,但是对象实现只有一个流操作符(<<)的重载,而不是一个转换为字符串。我想做这样的事情:

throw std::runtime_error("Error, encountered invalid value " + x);

其中x是重载(<<)的类型的实例。但是,上述操作无效,因为+未重载为与const char*兼容的类型。如果x是一个字符串(或者可转换为字符串),它可以工作,但我必须这样做:

std::stringstream s;
s << "Error, encountered invalid value " << x;
throw std::runtime_error(s.str());

如何在不添加任何重载或自定义函数的情况下获得与第一个示例一样简洁的内容。标准库是否提供了一些有用的功能?

1 个答案:

答案 0 :(得分:4)

您可以委托给一个函数:

template <typename T>
std::string stream(const T& x) {
    std::ostringstream ss;
    ss << x;
    return ss.str();
}

throw std::runtime_error("Error..." + stream(x));

这也是boost::lexical_cast的作用:

throw std::runtime_error("Error..." + boost::lexical_cast<std::string>(x));

或者您可以使用临时流,这涉及必须进行转换,因为operator<<通常只返回basic_ostream<char>&

throw std::runtime_error(
    static_cast<std::ostringstream&&>(std::ostringstream{} << "Error..." << x)
    .str() );

或者你可以将该逻辑包装成一个单独的类型,当流式传输时,将结果转换为string,以便娱乐:

struct ToStrT {
    friend std::string operator<<(std::ostream& os, ToStrT ) {
        return static_cast<std::ostringstream&&>(os).str();
    }
};

constexpr ToStrT ToStr{};

throw std::runtime_error(std::ostringstream{} << "Error..." << x << ToStr);