我们可以在noexcept规范中引用成员变量吗? [英] Can we refer to member variables in a noexcept specification?
问题描述
请考虑以下代码段:
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)会产生编译器错误
Is the use of the member variable m_elements
inside the noexcept
specifier legal? GCC 5.2 (C++17) yields the compiler error m_elements
was not declared in this scope. while clang 3.6 (C++17) compiles without any error.
如果我改用noexcept(std::declval<Tuple const&>().size())
,则两个编译器都不会产生错误.但是,如您所见,我创建了一个简单的示例类tuple
,其中Tuple
是否具有size
的合格重载至关重要.
Both compilers yield no error if I use noexcept(std::declval<Tuple const&>().size())
instead. However, as you can see, I've created a simple example class tuple
where it's crucial whether or not Tuple
has qualified overloads of size
.
从我的角度来看,编写noexcept(m_elements.size())
更直观,因为它恰好是函数体内的调用,并且考虑到vector
的size
方法是const
限定的(这使得m_elements
函数范围内的const对象.
From my point of view, it's more intuitive to write noexcept(m_elements.size())
cause it's exactly the call in the function body and it takes into account that the size
method of vector
is const
qualified (which makes m_elements
a const object in the scope of the function).
那么,合法用法是什么?如果两者相等,我应该使用哪个?在这种情况下,我应该完全使用noexcept
限定词吗?问题在于vector
函数是否将抛出,在大多数情况下都取决于Tuple
.
So, what's the legal usage? If both are equivalent, which should I use? Should I use noexcept
qualifiers at all in this scenario? The problem is that whether or not the vector
functions will throw depends in all most every case on Tuple
.
推荐答案
此处的lang语正确,这是gcc错误 [basic.scope.class] ,我的重点是:
Clang is correct here, this is gcc bug 52869. According to [basic.scope.class], emphasis mine:
在类中声明的名称的潜在范围不仅包括紧随其后的声明性区域. 名称的声明点,以及该类中非静态数据成员的所有函数体,默认参数,异常规范和括号或相等初始化器的声明点(包括嵌套的此类内容 类).
The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, default arguments, exception-specifications, and brace-or-equal-initializers of non-static data members in that class (including such things in nested classes).
m_elements
的范围包括size()
的 noexcept规范.
这篇关于我们可以在noexcept规范中引用成员变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!