Я пытаюсь написать общий класс конфигурации, который содержит параметры, подобные этим (значительно упрощено):
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);
};
Проблема в add_parameter_group
функция:
ParameterGroup& ParameterGroup::add_parameter_group(const string &token,
const bool &isRequired)
{
table[token] = Parameter(ParameterGroup(), isRequired);
return boost::any_cast<ParameterGroup>(table[token].value);
}
Возврат не компилируется с сообщением
error: invalid initialization of non-const reference of type ParameterGroup& from an
rvalue of type ParameterGroup
Я не понимаю почему. Согласно boost::any_cast
документация:
Если передан указатель, он возвращает аналогично уточненный указатель на значение содержимого в случае успеха, в противном случае возвращается значение null. Если T является ValueType, он возвращает копию удерживаемого значения, в противном случае, если T является ссылкой на (возможно, постоянный) ValueType, он возвращает ссылку на удерживаемое значение.
Почему это не возвращает ссылку так, как кажется?
T
не ссылочный тип, но ValueType
Таким образом, согласно документации, которую вы указали, вы получите значение.
Затем вы пытаетесь привязать это [временное] значение к ref-to-non-const
,
Пункт, который вы пытаетесь активировать:
если
T
ссылка на (возможно, постоянная квалификация)ValueType
, он возвращает ссылку на удерживаемое значение.
Итак, давайте сделаем T
ссылка на ValueType
:
boost::any_cast<ParameterGroup&>(table[token].value);
// ^^^^^^^^^^^^^^^
// |------------||
// ValueType (ref)
// |-------------|
// T
Теперь вы получите ссылку на удерживаемое значение, которое будет отлично связываться с типом возвращаемого значения.
Непосредственно взяты из boost :: any header
template<typename T> T any_cast(any &);
template<typename T> T any_cast(const any &);
template<typename ValueType> const ValueType * any_cast(const any *);
template<typename ValueType> ValueType * any_cast(any *);
Итак, вы видите, что boost :: any_cast возвращает копию, когда вы запрашиваете значение, поэтому вы не можете вернуть ссылку. Так что попробуйте any_cast с приведением ссылки