代码之家  ›  专栏  ›  技术社区  ›  deft_code

在实现非抛出交换时应该使用throw()吗?

  •  6
  • deft_code  · 技术社区  · 15 年前

    在实现非抛出交换习惯用法时,我应该使用 throw() ?

    namespace A
    {
       struct B
       {
         void swap( B& other ) throw()
         { /* fancy stuff that doesn't throw */ }
       };
    
       void swap( B& lhs, B& rhs ) throw()
       { lhs.swap(rhs); }
    }
    
    namespace std
    {
       template<>
       void swap( A::B& lhs, A::B& rhs ) throw()
       { lhs.swap(rhs); }
    }
    

    尤其是我担心 抛出() 专业化规范 std::swap .

    附加问题:
    当使用C++0X的时候,答案是不同的吗? noexcept 关键词?

    3 回复  |  直到 15 年前
        1
  •  4
  •   Steve Jessop    15 年前

    在C++ 03中,你可以把它放在那里,但是如果真正的东西不扔掉,它基本上只是文档。它可能影响性能,也可能不影响性能 try / catch(...) { std::unexpected(); } 围绕对函数的调用:它能否在不影响性能的情况下执行取决于实现。

    如果你打算使用 noexcept 操作人员 (5.3.7)在C++0x中,突然变得具有非抛出异常规范,从而操作员给出了“正确”的答案。我真的不知道 无例外 运算符是for的,但是如果它有一个聪明的通用用法,例如当某个东西不抛出时算法变得更有效,那么我想有必要将函数标记为不抛出,以获得任何好处。

    例如:

    void foo() noexcept;
    void bar();
    
    template <void(*FUNC)()>
    void generic_thing() {
        if (noexcept(FUNC()) {
            // this won't throw, perhaps we can somehow take advantage of that
            FUNC();
        } else {
            // this might throw
            FUNC();
        }
    }
    

    旧式异常规范( 动态异常规范 在C++ 0x中被弃用(在C++ 03中是毫无意义的)。

        2
  •  3
  •   wilhelmtell    15 年前

    这不是个好主意,不。原因是标准知道有时不可能强制执行 throw() 正确,这就是 抛出() 一开始就被带进来了。特别是,在模板的情况下,可能会抛出异常,也可能不会抛出异常,这取决于实例化,如果没有模板实例化,就不可能检查正确性。因此,标准甚至不需要编译器强制执行异常说明符;事实上,它 禁止 拒绝表达式的一种实现,“仅仅因为在执行时抛出或可能抛出包含函数不允许的异常”(15.4/11)。

    如果 抛出() 除了文档之外没有其他效果,因此应该将其注释掉;这样至少不会造成误导人类观察者的风险。

    这个案子 noexcept 完全不同。 无例外 有不同的原因;表现的原因。如果 可以保证编译器不会抛出异常,然后编译器允许自己执行一些优化。但是 你得自己检查。所以,如果真的 swap() 不抛出(也不应该抛出;那是它的葡萄干d’Ãtre)然后指定 无例外 是个好主意。

        3
  •  1
  •   Puppy    15 年前

    事实上,不例外规范是一个不错的主意,但事实上,它们阻碍了大多数代码,而不是帮助了大多数代码。没有人使用它们,它们在C++0X中被弃用。不要在现代C++中花费时间编写异常规范。

    推荐文章