Reputation: 3684
This is derived from Herb Sutter's gotw3 (http://www.gotw.ca/gotw/003.htm).
With the following class and FindAddr
function...
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;
}
I get a compile error because the Employee class has no conversion to string. I can see that such a conversion is not necessarily sensible, but for the purpose of the exercise, I added a naive conversion:
string::string(const Employee& e)
{
return e.name;
}
This gives me an error:
gotw3.cc:17:9: error: C++ requires a type specifier for all declarations
string::string(const Employee& e)
~~~~~~ ^
What am I doing wrong?
Upvotes: 4
Views: 13254
Reputation: 153899
Two things: first, you cannot add to an existing class without
modifying the class definition. If you have a class that you
want convertible to std::string
(or to double
or whatever),
you should define a conversion operator: in your case:
class Employee
{
// ...
operator std::string() const
{
return name; // Or whatever...
}
};
Second, the solution in your case isn't to provide an implicit
conversion, it is to use std::find_if
with an appropriate
matcher. In C++11, this may be done by using a lambda, but in
general (and in older versions of C++), you can always define
a functional type. For cases like this, where a class has an
natural "key", I would probably add a few member classes, along
the lines of:
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;
}
};
Additional functional types defining an ordering relationship, or equality of keys, might be in order as well.
Upvotes: 14
Reputation: 2108
There is no class string, there is a class template std::basic_string.
You should never modify anything in the std namespace.
For the purpose of conversion of a type to string you can add
Employee::operator std::string()
or define a
std::ostream& operator<<( const Employee& em, std::ostream& os );
- this way your type will work with lexical_cast
.
.. but what you actually need here is std::find_if()
.
Upvotes: 3