recently I wrote a post in which I asked for help in a problem I had in a C code. However, some people focused on a definition I put in one of my codes, which is:
std::map <std::string, std::pair<std::string, std::string>> map_example;
saying that this is considered a bad definition and that I should replace it.
I want to ask you if you can suggest me a better way to represent this data structure in a C code (possibly I want to avoid tuples), thanks.
EDIT
Here the link to the question I talked above.
CodePudding user response:
A common concern against std::pair
is poor naming of its members. Your code will be sprinkled with first
and second
when you probably could use better names.
Compare
struct customer_name_and_company {
std::string customer_name;
std::string company;
};
std::map<std::string, customer_name_and_company> m;
for (const auto& e : m) {
std::cout << e.customer_name << " " << e.company << "\n";
}
with the same code using a std::pair
:
std::map<std::string, std::pair<std::string,std::string> m;
for (const auto& e : m) {
std::cout << e.first << " " << e.second << "\n";
}
Neither the type nor the loop using the type uses proper names. Names are important! Consider you are looking only at the loop, then customer_name
and company
immediately tell you what those members are, while first
and second
requires you to track down previous definitions to make any sense out of the code.
std::pair
is good for generic code when you simply have no way to give names better than first
and second
because you don't know what they are. Also the standard library makes extensive use of std::pair
(for example std::map::insert
and others). I suppose that is to avoid inflation of simple types that would pollute the std
namespace. In your own code, on the other hand, any variable and type you can give a meaningful name, means more readable code.
CodePudding user response:
struct customer_name_and_company
{
customer_name_and_company(const std::string& _customer_name, const std::string& _company) :
customer_name{_customer_name},
company{_company} {}
std::string customer_name;
std::string company;
};
int main()
{
std::unordered_map <std::string, customer_name_and_company> umap {{"banana", customer_name_and_company{"1", "2"}}};
}
A similar implementation to the one above, but I consider it more efficient with std::unordered_map
, than with std::map
, in case there will be no collisions (in which case the complexity will be O(n)), but otherwise the complexity is O(1), for all operations (delete, search, insert), compared to O(logN).