C++ 为什么用转换运算符输出类对std::string不起作用?
:C++ 为什么用转换运算符输出类对std::string不起作用?,c++,templates,compiler-errors,implicit-conversion,C++,Templates,Compiler Errors,Implicit Conversion,: #包括 结构整型{ int i; 运算符int()常量noexcept{return i;} }; int main(){ Int i; i、 i=1; std::cout该运算符是一个自由的模板函数。当与模板函数参数匹配时,不会检查用户定义的转换,而是使用类型模式匹配(替换) 理论上,使用std::is_convertable的SFINAE重载可以实现您想要的功能,但是当操作符有点麻烦时,没有使用这种技术,但至少自己使用静态强制转换来重载它不会有太多工作。@chris我会改为重载,这就是我
#包括
结构整型{
int i;
运算符int()常量noexcept{return i;}
};
int main(){
Int i;
i、 i=1;
std::cout该运算符是一个自由的模板
函数。当与模板
函数参数匹配时,不会检查用户定义的转换,而是使用类型模式匹配(替换)
理论上,使用std::is_convertable
的SFINAE重载可以实现您想要的功能,但是当操作符有点麻烦时,没有使用这种技术,但至少自己使用静态强制转换来重载它不会有太多工作。@chris我会改为重载,这就是我的意思,重载>运算符如果operator&,std::basic_string const&
是basic_string
的内联、非模板朋友,它也会起作用。这可能是一个比SFINAE更好、更干净的实践。@Yakk是的,它会与自定义特征一起工作(无论如何它们都不是有用的)。在类模板中定义的非模板友元可以有效地模板化,而不是实例化。专门化规则根本不适用。问题是函数无法实例化,它只是作为类实例化的一个棘手的副作用生成的,并且只能由ADL找到。该构造非常适合于运算符重载。std::string
的一个在
中。我相信这一个工作的原因是它更专业,因此具有优先级,并且从Yakk的回答来看,不必推断模板参数。是的,它是,但似乎是一个模板,当您执行第一次隐式转换时它没有初始化,正如您在t中看到的那样我给你的链接。好吧,另一个问题是,我们不允许重载运算符来采用这样的标准类型。在这里,你解决了同样的问题:,你还可以提供一个到const char*的转换,这将适用于cout运算符,或者静态_cast,使编译器实例化正确的类型,我想你可以当我有一个这样的转换操作符时,我更喜欢好的类型,这样我的类型和它所使用的任何类型之间就少了一个用户定义的转换。这可以使必须强制转换它或将它存储在中间变量中有所不同。在我看来,将它用于需要std::string
的对象的可能性很大r比const char*
更有效。当然,在这个例子中,这两种方法同样有效?
#include <iostream>
struct Int {
int i;
operator int() const noexcept {return i;}
};
int main() {
Int i;
i.i = 1;
std::cout << i;
}
#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;
}
struct String {
std::string s;
operator std::string() const {return s;}
friend std::ostream& operator<<( std::ostream& os, String const& self) {
return os<<self.s;
}
};
#include <iostream>
#include <string>
std::ostream& operator<<(std::ostream& s, const std::string& str)
{
s << str.c_str();
return s;
}
struct String {
std::string s;
operator std::string() const {return s;}
};
int main() {
String s;
s.s = "hi";
std::cout << s;
}