简体   繁体   English

为什么编译器在执行operator<<时不能使用类的std::string转换函数?

[英]Why can't the compiler use the std::string conversion function of the class when perform operator<<?

Consider the following struct with a user-defined conversion function that can convert itself to const char* ;考虑以下带有用户定义转换函数的struct ,该函数可以将自身转换为const char*

struct S {
  operator const char*() { return "hello"; }
};

This work with <iostream> , we can print the struct S with no error message:这与<iostream>一起工作,我们可以打印struct S没有错误消息:

std::cout << S{} << '\n';

But if I change the return type to std::string :但是,如果我将返回类型更改为std::string

struct S {
  operator std::string() { return "hello"; }
};

I got this compiler error message:我收到此编译器错误消息:

<source>:11:13: error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'S')
11 |   std::cout << S{} << '\n';
   |   ~~~~~~~~~ ^~ ~~~
   |        |       |
   |        |       S
   |        std::ostream {aka std::basic_ostream<char>}
    <source>:11:18: note:   'S' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
11 |   std::cout << S{} << '\n';
   |                  ^

Why can't the compiler use the std::string conversion?为什么编译器不能使用std::string转换? Is there a difference between the conversion function of the built-in and class type?内置和类类型的转换函数有区别吗?

Because operator<< for std::basic_string is a template taking 3 template parameters:因为std::basic_string operator<<是一个带有 3 个模板参数的模板:

 template <class CharT, class Traits, class Allocator> std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const std::basic_string<CharT, Traits, Allocator>& str);

And implicit conversion won't be considered in template argument deduction :并且在模板参数推导中不会考虑隐式转换:

Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.类型推导不考虑隐式转换(上面列出的类型调整除外):这是重载解析的工作,稍后发生。

Then given std::cout << S{};然后给定std::cout << S{}; , the template parameter CharT , Traits and Allocator can't be deduced on the 2nd function argument. ,模板参数CharTTraitsAllocator不能在第二个函数参数上推导出来。

On the other hand, operator<< for const char* doesn't have such issue;另一方面, const char* operator<<没有这样的问题; given std::cout << S{};给定std::cout << S{}; , the template parameter CharT and Traits would be deduced only from the 1st function argument. ,模板参数CharTTraits只能从第一个函数参数中推导出来。 After deduction, the implicit conversion from S to const char* will be performed and the calling works well.推导后,将执行从Sconst char*的隐式转换,调用效果良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么输出带转换运算符的类不适用于std :: string? - Why does outputting a class with a conversion operator not work for std::string? 为什么编译器在与转换运算符一起使用时不能推导出模板参数? - Why can't the compiler deduce the template parameter when used with a conversion operator? 为什么编译器不执行类型转换? - Why doesn't the compiler perform a type conversion? 调用 operator== 时,MSVC 不会执行用户定义的到 std::nullptr_t 的隐式转换 - MSVC won't perform a user-defined implicit conversion to std::nullptr_t when invoking operator== 当模板参数要求 std::less 时,编译器如何在 std::set 中使用 T::operator&lt;<T> ? - How does a compiler use T::operator< in std::set when the template parameter asks for std::less<T>? 为什么转换函数不能与std :: string一起使用? - Why doesn't a conversion function work with std::string? 为什么我不能对std :: ofstream使用运算符bool() - Why can't I use operator bool() for std::ofstream 为什么我不能使用operator &lt;on&#39;std :: deque&#39;? - Why can't I use operator< on 'std::deque'? 为什么在模板化类之外返回 std::string 的 constexpr 函数不会编译? - Why doesn't constexpr function returning std::string doesn't compile when outside templated class? 为什么编译器不能优化std :: string concat? - Why compiler can not optimize std::string concat?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM