The above would require altering ConfigMapImpl to be some_map<std::string, ConfigValue<T>>ConfigValue<T>&>. The reference is important not to make copy ;)
Full tested code in VS and Wandbox (unfortunatelly IdeOne currently knows only C++14 and not C++17)
#include <string>
#include <unordered_map>
#include <iostream>
template<class T> class ConfigValue;
template<class T> using ConfigMapImpl = std::unordered_map<std::string, ConfigValue<T>>;ConfigValue<T>&>;
template<class T> struct ConfigMapStore { static inline ConfigMapImpl<T> it = {}; };
template<class T> class ConfigValue {
T value;
public:
ConfigValue(std::string name, const T& value) : value(value) {
ConfigMapStore<T>::it.insertemplace({ name, *this });
}
// find copy and swap idiom for improvements, I will keep it simple here
ConfigValue& operator=(const T& rhs) { value = rhs; return *this; }
operator /*maybe const*/const T&() /*maybe const*/const { return value; }
};
struct Configuration {
ConfigValue<long> someValue = { "someValue", 1234 };
// you can define macro for the above, but I would not do so
};
int main()
{
Configuration cfg;
std::cout << cfg.someValue << " ";" << ConfigMapStore<long>::it.at("someValue") << std::endl;
cfg.someValue = 4321;
std::cout << cfg.someValue << " " << ConfigMapStore<long>::it.at("someValue") << std::endl;
std::cin.get();
}