I want to create a class in c++. This class must manage with a collection.
OK, no problem, I would like to use operator[] of course but, in this case, my wish is to index not by position, but by name ==> that means using a string indexer.
It seems that something of this kind is not so nice to my compiler:
// In hpp
class myclass {
...
...
std::string operator[](const std::string& name);
}
// In cpp
std::string myclass::operator[](const std::string& name) {
...
}
// In main
myclass m;
std::string value = m["Name"];
Compiler tells me that he cannot solve this because operator[const char[5]] does not exists.
OK OK
I could figure this...
Compiler thinks that by calling m["Name"] I'm trying to call an operator admitting a char* and not a string... ok
Let's change the code with operator[] allowing a char* as parameter... nothing.
Can somebody tell me how to achieve such a result in c++ in a best practice way? I suppose that is a common problem to index by string and not by integer...
Thank you.
It should work fine. See this example which compiles and works ok for me:
#include <iostream>
#include <string>
class MyClass
{
public:
std::string operator[] (const std::string& key) { std::cout << key << std::endl; return key; }
};
int main()
{
MyClass obj;
std::string s = obj["50"];
std::cout << s << std::endl;
}
And I see no reason it should not, since std::string has implicit constructor taking const char*
so the conversion should be automatic.
Edit: From the comment it seems your problem was with your main beeing like this:
int main()
{
MyClass obj();
std::string s = obj["50"];
std::cout << s << std::endl;
}
The reason:
An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized.
[ Note: since () is not permitted by the syntax for initializer,
X a ();
is not the declaration of an object of class X, but the declaration of a function taking no argument and returning an X.
The form () is permitted in certain other initialization contexts (5.3.4, 5.2.3, 12.6.2). — end note ]
The code that you have provided should compile okay (providing the operator
is public
and you terminate your class
declaration with a ;
). I suspect the compiler error is somewhere else.
Personally, I would use std::map<std::string, std::string>
as the container class.
#include <string>
#include <map>
#include <assert.h>
int main()
{
std::map<std::string, std::string> m;
m["Foo"] = "Bar";
m["Fez"] = "Baz";
assert(m["Foo"] == "Bar");
assert(m["Fez"] == "Baz");
}