operator std::string () const;
替换为operator char * () const;
并相应地更改了实施。这允许隐式转换,但是,由于某种原因,unsigned long int运算符优先于char *运算符,这只是感觉不对...而且,我不想暴露讨厌的C之类的东西,比如char * class,当我有std :: string时。我有一种预感,我的CustomizedInt类需要继承一些东西才能支持我想要的功能。有人可以详细说明迈克关于std::basic_string
的评论吗?我不确定我是否理解它。
我有这段代码:
#include <string>
#include <sstream>
#include <iostream>
class CustomizedInt
{
private:
int data;
public:
CustomizedInt() : data(123)
{
}
operator unsigned long int () const;
operator std::string () const;
};
CustomizedInt::operator unsigned long int () const
{
std::cout << "Called operator unsigned long int; ";
unsigned long int output;
output = (unsigned long int)data;
return output;
}
CustomizedInt::operator std::string () const
{
std::cout << "Called operator std::string; ";
std::stringstream ss;
ss << this->data;
return ss.str();
}
int main()
{
CustomizedInt x;
std::cout << x << std::endl;
return 0;
}
打印“Called operator unsigned long int; 123”。我的问题是这些:
答案 0 :(得分:8)
删除运算符unsigned long int后,为什么需要显式地将x转换为std :: string?为什么不直接调用隐式转换运算符(std :: string)?
字符串的<<
版本是一个模板,由std::basic_string
模板的参数进行参数化(std::string
本身是该模板的特化)。它只能通过依赖于参数的查找来选择,并且仅在参数实际上是std::basic_string
的特化时才有效,而不是可转换为该参数。
是否有任何文档可以解释允许哪些隐式强制转换以及哪些是优先顺序?
规则非常复杂,您需要阅读完整故事的C ++标准。简单的经验法则是隐式转换不能包含多个用户定义的转换,并且(如您所知)隐式转换的结果不能用于通过依赖于参数的查找来选择模板特化。
我不确定我是否完全理解相关的警告。有人可以概述一下吗?
我也不完全理解他们;隐式转换,名称查找和模板特化(以及可能是我现在无法想到的其他因素)之间的相互作用相当复杂,而且大多数人并不倾向于全部学习它们。有很多情况下隐式转换不会发生,而其他情况可能会发生在您不期望的情况下;就个人而言,我发现在大多数情况下避免隐式转换更容易。
仅仅定义公共方法ToUnsignedLongInt和ToString会更好吗?
这可能是一个好主意,以避免不必要的转换。您可以通过保留问题来解决问题,并在必要时明确使用它们:
std::cout << std::string(x) << std::endl;
在C ++ 11中,您可以声明它们explicit
,以便它们只能以这种方式使用。在我看来,如果可以,这将是最好的选择;否则,我会按照你的建议使用显式转换函数。
顺便说一下,main()
的返回类型必须是int
,而不是void
。