编译器无法做隐式类型转换。
- C/C++ code
#include<iostream>#include<string>class Test{ public: operator const std::string() const{ return std::string("can you feel me ?"); }};class Foobar{ public: operator const int() const{ return 0; }};int main(){ Test t; //std::cout << t << std::endl; //error std::cout << static_cast<std::string>(t) << std::endl; Foobar f; std::cout << f << std::endl; //success}
为什么编译器(MSVC 7.1)不将变量t隐式转换成string,而后调用 ostream& operator << (const ostream&, const basic_string &)进行输出?
[解决办法]
这个不是因为实例化的缘故,而是编译器的处理这个问题的步骤问题。对于你那样的输出 肯定是查找operator<<这个函数的重载,查找失败就已经报错了。它不会考虑是否做转型这些尝试。因为一旦这样,那么更容易出问题,比如你还里面还有个operator int(){}这样的转型的话 岂不是就悲剧了呢?因为operator<<对int和string都是可以的。所以后面的转型编译器根本不予考虑。
[解决办法]
欲达成成功的隐式转换,大致需要两个条件:
一是有明确的目标类型;
二是有可行的转换路径。
对于cout<<t,虽然具有可行的转换路径,但缺乏明确的目标类型,因为可作为插入操作符的右操作数的类型有很多,编译器不知道你想转换成哪一个,直到你通过显式转换明确告诉它你的目标类型。
[解决办法]
- C/C++ code
#include<iostream>#include<string>class Test{ public: /* operator const std::string() const{ return std::string("can you feel me ?"); } */ operator const int() const{ return 10; }};class Foobar{ public: operator const int() const{ return 0; }};int main(){ Test t; std::cout << t << std::endl; //error std::cout << static_cast<int>(t) << std::endl; Foobar f; std::cout << f << std::endl; //successr return 0;}
[解决办法]
lz你好,我想原因应该是隐式转换不参与模板实参的推导。
Test-String(模板)->std::cout(模板)而这个对于c++是不允许的!
例如:
- C/C++ code
template <typename T>class A {};class StringValue {public: operator A<int>() const { return A<int>(); }};template <typename T>void f(A<T>) {}void f2(A<int>) {}int main(){ StringValue sv; f(sv); // ERROR f2(sv); // OK}
[解决办法]