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