3

这源自 Herb Sutter 的 gotw3 (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)
~~~~~~  ^

我究竟做错了什么?

4

2 回答 2

13

两件事:首先,您不能在不修改类定义的情况下添加到现有类。如果您有一个想要转换为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;
    }
};

定义排序关系或键相等的其他功能类型也可能是有序的。

于 2012-12-13T14:03:23.690 回答
3

没有类字符串,有类模板std::basic_string。

您永远不应该修改 std 命名空间中的任何内容。

为了将类型转换为字符串,您可以添加

Employee::operator std::string()

或定义一个

std::ostream& operator<<( const Employee& em, std::ostream& os );- 这样您的类型将与lexical_cast.

..但你真正需要的是std::find_if().

于 2012-12-13T14:01:10.860 回答