2016-03-08 38 views
7

请考虑下面的代码片段:我们可以在noexcept规范中引用成员变量吗?

template<class Tuple> 
class vector 
{ 
public: 
    typename Tuple::size_type size() const noexcept(noexcept(m_elements.size())) { 
     return m_elements.size(); 
    } 

private: 
    Tuple m_elements; 
}; 

class tuple 
{ 
public: 
    using size_type = std::size_t; 

    size_type size() const { return 0; } 
    size_type size() noexcept { return 0; } 
};  

int main() 
{ 
    vector<tuple> x; 
    static_assert(noexcept(x.size()), "x.size() might throw"); 

    return 0; 
} 

里面的noexcept符合法使用成员变量m_elements的? GCC 5.2 (C++17) yields the compiler errorm_elements未在此范围内申报。而clang 3.6 (C++17) compiles without any error

如果我用noexcept(std::declval<Tuple const&>().size())代替,两个编译器都不会产生错误。但是,正如您所看到的,我创建了一个简单的示例类tuple,其中Tuple是否具有合格的size过载是至关重要的。

从我的角度来看,它更直观地写noexcept(m_elements.size())因为它是在函数体完全通话,并考虑到的vectorsize方法是const合格(这使得m_elements一个const对象的范围功能)。

那么,法律用法是什么?如果两者都相同,我应该使用哪一个?在这种情况下,我应该使用noexcept限定符吗?问题在于vector函数是否会抛出取决于Tuple的大部分情况。

+0

我想说明的是[有关在noexcept规范中使用成员变量的问题](http://stackoverflow.com/questions/27241938/noexcept-depending-on-method-of - 成员),但请注意,这个问题与C++ 11相关,并且由(某些未知版本的)clang产生的编译器错误。 – 0xbadf00d

回答

5

锵在这里是正确的,这是一个海湾合作委员会的错误。据[basic.scope.class],重点煤矿:

在一个类中声明的名称的潜在范围不仅包括以下声明的 名称的点声明区,也是所有函数体中,默认参数,例外 - 规范该类中的非静态数据成员的括号或相等初始值设定项(包括嵌套的 类中的这些内容)。

m_elements范围包括用于size()noexcept规格

相关问题