为什么输出带有转换运算符的类不适用于std :: string? [英] Why does outputting a class with a conversion operator not work for std::string?

查看:691
本文介绍了为什么输出带有转换运算符的类不适用于std :: string?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个工作,打印1

#include <iostream>

struct Int {
    int i;
    operator int() const noexcept {return i;}
};

int main() {
    Int i;
    i.i = 1;
    std::cout << i;
}

但是,这无法在GCC 4.8.1上编译

#include <iostream>
#include <string>

struct String {
    std::string s;
    operator std::string() const {return s;}
};

int main() {
    String s;
    s.s = "hi";
    std::cout << s;
}

以下是错误的相关部分:

Here are the relevant parts of the error:



错误:没有匹配'operator<<'(操作数类型是std :: ostream {aka std :: basic_ostream}和'String')

std :: cout<< s;

error: no match for ‘operator<<’ (operand types are ‘std::ostream {aka std::basic_ostream}’ and ‘String’)
std::cout << s;

snip

template std :: basic_ostream< _CharT,_Traits>& std :: operator<<<(std :: basic_ostream< _CharT,_Traits>& const std :: basic_string< _CharT,_Traits,_Alloc>&)

operator< ,_Traits>& __os,

template std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<<(basic_ostream<_CharT, _Traits>& __os,

/ usr / include / c ++ / 4.8 / bits / basic_string.h:2753:5:note:template argument deduction /

main.cpp:25:18:note:'String'不是从'const std :: basic_string< _CharT,_Traits,_Alloc>'

派生的std :: cout< ;< s;

/usr/include/c++/4.8/bits/basic_string.h:2753:5: note: template argument deduction/substitution failed:
main.cpp:25:18: note: ‘String’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
std::cout << s;


我只使用 std :: cout std :: string ,它们有相同的模板参数我真的不知道为什么这将无法获取隐式为什么它使用 int ,但不是 std: :string ?

I only use std::cout and std::string, which have the same template arguments. I'm really not sure why this wouldn't be able to pick up the implicit conversion like it did for Int. Why does it work with int, but not std::string?

推荐答案

该操作符是一个免费的模板函数,当与模板函数参数匹配时,不会检查用户定义的转换,而是使用类型模式匹配(替换)。

That operator is a free template function. User defined conversions do not get checked when matching against a template function arguments, it instead uses type pattern matching (substitution).

理论上,使用 std :: is_convertable<> 的SFINAE重载将能够做你想要的,当运算符 std :: string 输出到 basic_ostream< char>

In theory a SFINAE overload using std::is_convertable<> would be able to do what you want, but that technique was not used when operator<< that outputs a std::string to a basic_ostream<char> was defined.

手动重载以将您的类输出到 basic_ostream< ...> 会解决您的问题。

A manual overload to output your class to basic_ostream<...> will fix your problem.

这篇关于为什么输出带有转换运算符的类不适用于std :: string?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆