Let's say i have this code :
#include <iostream>
#include <unordered_map>
#include <functional>
using const_string_ref = std::reference_wrapper<const std::string>;
namespace std
{
template<>
struct hash<const_string_ref>
{
size_t operator()(const const_string_ref& ref) const
{
return std::hash<std::string>()(ref);
}
};
bool operator==(const const_string_ref& lhs,
const const_string_ref& rhs)
{
return (lhs.get() == rhs.get());
}
}
class test
{
public:
void process(const std::string& action)
{
(this->*(ACTIONS_PROCESSORS_MAP_.at(action)))();
}
private:
using action_processor = void (test::*)();
using actions_map = std::unordered_map<const_string_ref, action_processor>;
private:
static const std::string FIRST_KEY_;
static const std::string SECOND_KEY_;
static const actions_map ACTIONS_PROCESSORS_MAP_;
private:
void first_action()
{
std::cout << "first works" << std::endl;
}
void second_action()
{
std::cout << "second works" << std::endl;
}
};
const std::string test::FIRST_KEY_ = "first";
const std::string test::SECOND_KEY_ = "second";
const test::actions_map test::ACTIONS_PROCESSORS_MAP_ =
{{std::cref(FIRST_KEY_), &test::first_action},
{std::cref(SECOND_KEY_), &test::second_action}};
int main()
{
test t;
t.process("first");
t.process("second");
return 0;
}
The main question is:
Am i guaranteed that at the point of entering the main function the references contained within the reference_wrapper used as keys in test::ACTIONS_PROCESSORS_MAP_ will be corectly initialized to valid references to test::FIRST_KEY_ and test::SECOND_KEY_ respectivly, independently of the static order initialization ?
This question could be more generally summed up as :
Are pointers/references to satatic objects valid even before these objects initialization (i.e can the address change at some point) ?