I'm not even sure this question's title is correct. What I'm trying to do is fairly gnarly to me so I don't even know how to describe it in a concise manner. Sorry about that.
I have a container of values which are wrapped in some kind of "safe" value class. I need a function that takes a pointer to that container, a reference to one of its member and the following happens:
If the pointer passed is valid, the function returns the value inside the wrapped value.
If the pointer passed is nullptr, the function returns a default-constructed value.
Anyhoo, here some code.
template<typename T>
class Wrapped {
T t;
public:
T& operator*() {
return t;
}
};
class Container {
public:
Wrapped<int> i;
Wrapped<string> s;
};
// Compiler error with R.
// I'd like R to be the type returned by doing operator* on the member that's represented by M.
// I've tried about 50 different versions of declarations to declare the type of R. This one feels like it most closely represents what I'm trying to achieve.
// R should be the T in Wrapped<T>.
template <typename T, typename M, typename R = decltype(declval<M>().operator*())>
R value_or_default(T* object, M member, R default_value = R{})
{
object ? *((*object).*member) : default_value;
}
Container c;
auto actual_int = value_or_default(&c, &Container::i); // Returns *(c.i).
auto default_string = value_or_default(nullptr, &Container::s); // Returns string{}.
Aucun commentaire:
Enregistrer un commentaire