I'm trying to write a generic configuration class that holds parameters like this (simplified greatly):
class Parameter
{
public:
Parameter(boost::any value, bool isRequired)
: value(value), isRequired(isRequired) {}
bool isSet;
bool isRequired;
boost::any value;
};
class ParameterGroup
{
public:
map<std::string, Parameter> table;
// references for chaining
ParameterGroup& add_parameter_group(const string &token, const bool isRequired);
ParameterGroup& add_parameter(const string &token, const bool isRequired);
template<typename T>
T& get_parameter(const string &token);
};
The problem is in the add_parameter_group
function:
ParameterGroup& ParameterGroup::add_parameter_group(const string &token,
const bool &isRequired)
{
table[token] = Parameter(ParameterGroup(), isRequired);
return boost::any_cast<ParameterGroup>(table[token].value);
}
The return fails to compile with the message
error: invalid initialization of non-const reference of type ParameterGroup& from an
rvalue of type ParameterGroup
I don't see why. According to the boost::any_cast
documentation:
If passed a pointer, it returns a similarly qualified pointer to the value content if successful, otherwise null is returned. If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference to (possibly const qualified) ValueType, it returns a reference to the held value.
Why is this failing to return a reference as it seems it should?
T
is not a reference type, butValueType
, so according to the documentation you quoted, you get a value.You are then trying to bind this [temporary] value to a ref-to-non-
const
.The clause you are trying to activate is:
So, let's make
T
a reference toValueType
:Now you'll get a reference to the held value, which'll bind just fine to the return type.