【问题标题】:Boost::any reference to stored value not compilingBoost::any 对存储值的引用未编译
【发布时间】:2013-12-04 16:02:06
【问题描述】:

我正在尝试编写一个通用配置类来保存这样的参数(大大简化了):

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 是对(可能是 const 限定的)ValueType 的引用,则返回对保存值的引用。

为什么它没有返回看起来应该的引用?

【问题讨论】:

    标签: c++ boost boost-any


    【解决方案1】:

    T不是引用类型,而是ValueType,所以根据你引用的文档,你会得到一个值。

    然后,您尝试将此 [临时] 值绑定到 ref-to-non-const。

    您要激活的子句是:

    如果 T 是对(可能是 const 限定的)ValueType 的引用,则它返回对所持有值的引用。

    所以,让我们将T 引用为ValueType:

    boost::any_cast<ParameterGroup&>(table[token].value);
    //              ^^^^^^^^^^^^^^^
    //              |------------||
    //                ValueType (ref)
    //              |-------------|
    //                     T
    

    现在您将获得对所持有值的引用,该引用将很好地绑定到返回类型。

    【讨论】:

    • 啊哇。我要去某个角落,悄悄地踢自己一脚。回想起来,这似乎很明显。
    • @Fadecomic:它发生了。 :-)
    • @Fadecomic 我不同意。你的问题帮助了我。提取 ref 应该是文档中的一个示例。
    【解决方案2】:

    直接取自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 投射参考

    【讨论】:

    • 嗯,不;正如文档所说,这取决于 T 是什么。
    猜你喜欢
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    • 1970-01-01
    • 2012-02-10
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多