Daniel Lemire's blogAccessing the attributes of a struct in C++ as array elements?In C++, it might be reasonable to represent a URL using a class or a struct made of several strings, like so:
struct basic {
std::string protocol;
std::string username;
std::string password;
std::string hostname;
std::string port;
std::string pathname;
std::string search;
std::string hash;
};
You might associate to each component (protocol, username, etc.) an index, like so:
enum class component {
PROTOCOL = 0,
USERNAME = 1,
PASSWORD = 2,
HOSTNAME = 3,
PORT = 4,
PATHNAME = 5,
SEARCH = 6,
HASH = 7,
};
What you might like to do then is to access a component by its index. The following code might do:
std::string& get_component(basic& url, component comp) {
switch (comp) {
case component::PROTOCOL: return url.protocol;
case component::USERNAME: return url.username;
case component::PASSWORD: return url.password;
case component::HOSTNAME: return url.hostname;
case component::PORT: return url.port;
case component::PATHNAME: return url.pathname;
case component::SEARCH: return url.search;
case component::HASH: return url.hash;
}
}
But what if you are constantly accessing values by their indexes? You might be concerned that the overhead of the switch/case could be too much.
Instead, you might flip the data structure around and store the values in an array within the data structure. The following might work:
struct fat {
std::array data;
std::string &protocol = data[0];
std::string &username = data[1];
std::string &password = data[2];
std::string &hostname = data[3];
std::string &port = data[4];
std::string &pathname = data[5];
std::string &search = data[6];
std::string &hash = data[7];
};
With this new data structure, getting a component by its index becomes simpler:
std::string& get_component(fat& url, component comp) {
return url.data[int(comp)];
};
Unfortunately, each reference in the new fat data structure might use 8 bytes. That is not a concern if you expect to have few instances of the data structures. However, if you do, you might want to avoid the references. You might try to replace the references by simple methods:
struct advanced {
std::array data;
std::string &protocol() { return data[0]; }
std::string &username() { return data[1]; }
std::string &password() { return data[2]; }
std::string &hostname() { return data[3]; }
std::string &port() { return data[4]; }
std::string &pathname() { return data[5]; }
std::string &search() { return data[6]; }
std::string &hash() { return data[7]; }
};
It is not entirely satisfactory as it requires calling methods instead of accessing attributes.
I am not sure whether you can do any better currently in C++.
source