是否可以使用cout从用户定义的类型自动转换为std :: string?

Mic*_*lis 3 c++ casting stdstring user-defined-types implicit-cast

在问题中,如果我在我的类中定义一个字符串运算符:

class Literal {
  operator string const () {
    return toStr ();
  };

  string toStr () const;
};
Run Code Online (Sandbox Code Playgroud)

然后我用它:

Literal l1 ("fa-2bd2bc3e0");
cout << (string)l1 << " Declared" << endl;
Run Code Online (Sandbox Code Playgroud)

使用显式转换一切正常,但如果我删除(字符串)编译器说它需要在std :: string中声明的强制转换运算符.它不应该自动投射我的类型?解决:我正在重载运算符<<(ostream&os,const Literal&l).

RC.*_*RC. 10

不.. std :: string必须有一个构造函数,将Literal作为参数.

你可以做的是为你的Literal类重载operator <<并将它转换并插入到那里的流中.

ostream &operator <<(std::ostream &stream, const Literal &rhs)
{
    stream << (string) rhs;
    return stream;
}
Run Code Online (Sandbox Code Playgroud)

  • 在确定函数调用是否可行时,转换构造函数和转换运算符是等效的.编译器不会在这里进行隐式转换的真正原因更复杂. (3认同)
  • 如果您计划将您的类与流操作一起使用,那么您真的应该重载<<和>>运算符.它使得使用类更清洁. (2认同)
  • c ++拥有自己的一组转换运算符.不要使用c演员表 (2认同)

asc*_*ler 5

简短回答:继续使用演员toStr(),或编写自己的operator<<功能.(我宁愿l1.toStr()(string)l1.)

答案很长:如果标准库有一个功能,这可能会有效

std::ostream& operator<<( std::ostream&, std::string const& );
Run Code Online (Sandbox Code Playgroud)

它几乎可以做到,但不是技术上的.这两个ostreamstring真的模板实例的类型定义.并且有一个模板功能可以将一个插入另一个.

// This is somewhat simplified.  For the real definitions, see the Standard
// and/or your complying implementation's headers.
namespace std {
  typedef basic_string<char> string;
  typedef basic_ostream<char> ostream;

  template <typename CharT>
  basic_ostream<CharT>& operator<<(
    basic_ostream<CharT>&, 
    basic_string<CharT> const&);
}
Run Code Online (Sandbox Code Playgroud)

因此,当你使用cout << str的类型str是什么时std::string,它可以计算出使用该模板函数CharT = char.

但是C++不允许你让编译器在同一个调用中找出隐式类型转换(Literalto string)和推断模板函数模板参数(CharT = char).