代码之家  ›  专栏  ›  技术社区  ›  Danra Bathsheba

如何确保boost::optional<T>对象在发布版本中初始化?

  •  3
  • Danra Bathsheba  · 技术社区  · 16 年前

    但是,当取消对未初始化可选项的引用时,我希望抛出一个异常——有没有办法在发布版本中获得这种行为?如果没有,是否有其他类似的库具有这种行为?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Kornel Kisielewicz    16 年前

    可选的是 设计 容许 在函数中抛出异常,但返回一个成功/失败值。

    也许您应该始终返回一个值,如果函数失败,则抛出函数内部?

        2
  •  3
  •   alfC    10 年前

    你可以定义 boost::assertion_failed(...) BOOST_ENABLE_ASSERT_HANDLER 从中抛出异常 boost::optional .

    代码:

    #include<boost/exception/to_string.hpp>
    
    namespace boost{
    void assertion_failed(char const* expr, char const* function, char const* file, long line){
        throw std::runtime_error(std::string()
            + expr + 
            " from " + function +
            " at " + file + ":" + boost::to_string(line)
        );
    }
    }
    
    #define BOOST_ENABLE_ASSERT_HANDLER
    #include <boost/optional.hpp>
    #undef BOOST_ENABLE_ASSERT_HANDLER
    
    int main(){
        double d = *boost::optional<double>{}; // throws! (width fairly useful msg)
        (void)d;
    }
    

    terminate called after throwing an instance of 'std::runtime_error'
      what():  this->is_initialized() from reference_type boost::optional<double>::get() [T = double] at /usr/include/boost/optional/optional.hpp:992
    

    其他参考资料: http://boost.2283326.n4.nabble.com/optional-How-to-make-boost-optional-throw-if-trying-to-access-uninitialized-value-td2591333.html

    笔记:

    1) 它可能需要对 assertion_failed 总的来说是有用的。如果你想抛出不同类型的异常,除了在 断言失败 就我的口味而言,(也是):

    namespace boost{
    void assertion_failed(char const* expr, char const* function, char const* file, long line){
        if(std::string("this->is_initialized()") == expr) throw std::domain_error("optional is not intialized");
        throw std::runtime_error(std::string()
            + expr + 
            " from " + function +
            " at " + file + ":" + boost::to_string(line)
        );
    }
    }
    

    assert 这不是一个好的选择。在我看来,这个词有很多用法 在不涉及函数返回的上下文中。

    3) 现在有一个 std::experimental::optional 版本奇怪的是,他们决定在考虑价值时对这个问题持不可知论 * (自 未经检查 但是 这个 .value() 会员可以投掷 std::experimental::bad_optional_access 例外。这是一个有趣的设计选择(加上这两种方式都没有) 断言 S我认为这是正确的。

    推荐文章