如何使用std::stringstream将自定义结构体转换为std::string?

问题描述 投票:0回答:1

我想将一个自定义的结构体转换为std::string,我想到使用std::stringstream,因为它可以轻松地将各种类型转换为std::string。

template<typename T>
std::string type_to_string(const T &in) {
    std::stringstream ss;
    ss << in;
    return ss.str();
}

struct st_Key {
    std::string a;
    int b;
    char c;
    ...

    template<typename OStream>
    friend OStream &operator<<(OStream &os, const st_Key &c) {
        // wanted form to output
        return os << "a"
                  << "=[" << c.a<< "]"
                  << "b"
                  << "=[" << c.b<< "]"
                  << "c"
                  << "=[" << c.c<< "]";
    }
};

我想如何转换为 std::string

std::string s = type_to_string(st_Key{"a", 1, 'c'});

但是编译时出现一些错误:

<source>: In instantiation of 'OStream& operator<<(OStream&, const st_Key&) [with OStream = std::__cxx11::basic_stringstream<char>]':
<source>:14:8:   required from 'std::string type_to_string(const T&) [with T = st_Key; std::string = std::__cxx11::basic_string<char>]'
<source>:36:35:   required from here
<source>:31:36: error: invalid initialization of reference of type 'std::__cxx11::basic_stringstream<char>&' from expression of type 'std::basic_ostream<char>'
   31 |                   << "=[" << c.c<< "]";
      |                                    ^~~

那么这有什么问题呢? https://godbolt.org/z/q6zo8r98s

c++17
1个回答
0
投票

标准库中包含的所有

operator<<
函数不能直接与特定的流类型一起使用。相反,他们采用
std::basic_ostream<CharT, Traits>&
作为参数,并将其用作返回类型。

在您的

operator<<(OStream&, const st_Key&)
中,您尝试返回
std::stringstream&
,但 return 语句中使用的输出运算符仅返回基类。将基类引用强制转换回派生类型不是隐式的。

您可以执行与 std 函数相同的操作,并使用

basic_ostream
作为类型,而不是特定流类型的模板:

template<typename CharT, typename Traits>
friend std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os, const st_Key &c) {
    // wanted form to output
    return os << "a"
              << "=[" << c.a<< "]"
              << "b"
              << "=[" << c.b<< "]"
              << "c"
              << "=[" << c.c<< "]";
}
© www.soinside.com 2019 - 2024. All rights reserved.