Можем ли мы ссылаться на переменные-члены в спецификации 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;
}
Является ли использование переменной-членаm_elements
внутриnoexcept
спецификатор юридический?GCC 5.2 (C ++ 17) выдает ошибку компилятора m_elements
не был объявлен в этой области, в то время какclang 3.6 (C ++ 17) компилируется без ошибок.
Оба компилятора не выдают ошибок, если я используюnoexcept(std::declval<Tuple const&>().size())
вместо. Однако, как вы можете видеть, я создал простой пример классаtuple
где это важно или нетTuple
квалифицированные перегрузкиsize
.
С моей точки зрения, писать интуитивно понятнееnoexcept(m_elements.size())
потому что это именно вызов в теле функции, и он принимает во внимание, чтоsize
методvector
являетсяconst
квалифицированный (что делаетm_elements
константный объект в области действия функции).
Итак, что такое законное использование? Если оба эквивалентны, что я должен использовать? Должен ли я использоватьnoexcept
Отборочные на всех в этом сценарии? Проблема заключается в том, является лиvector
функции будут выбрасывать зависит во всех большинстве случаев отTuple
.