When something goes wrong, the first thing is to ask myself what did I do wrong. I don’t like just throwing the blame. And when I saw the not declared in this scope error related to the noexcept operator, I was sure I was missing something. Maybe I had accidentally used a compiler extension, maybe I used something that’s undefined behavior. But I didn’t think it could be a GCC noexcept compiler bug.
I have a container that encapsulates a vector, for which I wanted to have a noexcept swap method. Ignore the implementation itself, the idea is I wanted to declare the method noexcept if the swap operations on the items I wanted to swap are also noexcept. It can be any other case that implies noexcept.
#include <vector> #include <utility> #include <cassert> struct Container { std::vector<int> elements{}; std::size_t count{}; void swap(Container &c) noexcept(noexcept(elements.swap(c.elements)) && noexcept(std::swap(count, c.count))) { elements.swap(c.elements); std::swap(count, c.count); } }; int main() { Container a{{1, 2}, 2}; Container b{{3, 4, 5}, 3}; a.swap(b); assert(a.elements == (std::vector<int>{3, 4, 5})); assert(a.count == 3); assert(b.elements == (std::vector<int>{1, 2})); assert(b.count == 2); }
This tells that Container’s swap is noexcept if both swaps of elements and count are noexcept:
void swap(Container &c) noexcept(noexcept(elements.swap(c.elements)) && noexcept(std::swap(count, c.count)));
MSVC and Clang compile this, but GCC needs a newer version because on older ones it has the bug [DR 1207] “this” not being allowed in noexcept clauses, which I’ve found in this discussion.
If you see one of the following errors, try to update your compiler:
-
- ‘elements’ was not declared in this scope
- invalid use of incomplete type ‘struct Container’
- invalid use of ‘this’ at top level