这是源自Herb Sutter的故事(http://www.gotw.ca/gotw/003.htm)。
使用以下类和FindAddr
函数...
using std::string;
using std::list;
class Employee
{
public:
Employee(const string& n, const string& a) : name(n), addr(a) { }
string name;
string addr;
};
string FindAddr(const list<Employee>& l, const string& name)
{
string addr;
list<Employee>::const_iterator i = find(l.begin(), l.end(), name);
if (i != l.end()) {
addr = (*i).addr;
}
return addr;
}
我收到编译错误,因为Employee类没有转换为字符串。我可以看到这样的转换不一定是明智的,但为了练习的目的,我添加了一个天真的转换:
string::string(const Employee& e)
{
return e.name;
}
这给了我一个错误:
gotw3.cc:17:9: error: C++ requires a type specifier for all declarations
string::string(const Employee& e)
~~~~~~ ^
我做错了什么?
答案 0 :(得分:9)
两件事:首先,你不能在没有的情况下添加到现有的类
修改类定义。如果你有一个班级
想要转换为std::string
(或double
或其他),
你应该定义一个转换运算符:在你的情况下:
class Employee
{
// ...
operator std::string() const
{
return name; // Or whatever...
}
};
其次,你的案例中的解决方案不是提供隐含的
转换,是使用适当的std::find_if
匹配器。在C ++ 11中,这可以通过使用lambda来完成,但是在
一般(在旧版本的C ++中),您始终可以定义
功能型。对于这样的情况,一个班级有一个
自然“关键”,我可能会添加一些成员类
以下几行:
class Match : std::unary_function<Employee, bool>
{
std::string myName;
public:
explicit Match( std::string const& name )
: myName( name )
{
}
bool operator()( Employee const& toBeMatched ) const
{
return toBeMatched.name == myName;
}
};
定义排序关系的其他功能类型, 或者按键相等,也可以按顺序排列。
答案 1 :(得分:2)
没有类字符串,有一个类模板std :: basic_string。
你永远不应该修改std命名空间中的任何内容。
为了将类型转换为字符串,您可以添加
Employee::operator std::string()
或定义
std::ostream& operator<<( const Employee& em, std::ostream& os );
- 这样您的类型就可以使用lexical_cast
。
..但您实际需要的是std::find_if()
。