Why the clang says call to deleted constructor of 'Block<Tuple>::Self' (aka 'Block<Tuple>')
in the call of Block<Tuple>::a1()
when I delete the move constructor?
c++17 clang version 9.0.0 (tags/RELEASE_900/final) Target: x86_64-pc-linux-gnu Thread model: posix InstalledDir: /usr/bin
template<typename tRecord>
struct Block {
using Self = Block<tRecord>;
Size mUsedBytes;
bool mModified;
union Data {
char mBytes[4_KB];
tRecord mRecord;
};
Data mData;
Block() {
mardCpp::Log::info("constructing");
};
Block(const Block &block) = delete;
Block(Block &&block) = delete;
static Self a1() {
Self block;
return block;
}
static Self a2() {
return Self();
}
};
From what I've readed, I could have garanteed rvo if I deleted the copy and move constructors. The compiler would complain in situations where he could not do rvo and the code would not compile. For instance, when I delete the copy constructor and define the move one with just throwing an error, he actually optimizes the calling of a1, since I got no errors. But when I delete the move constructor, the code does not even compile.
This code:
static Self a1() {
Self block;
return block;
}
is not part of the so-called "guaranteed copy elision". It still has the same behaviour as in older versions of C++, i.e. it is a copy elision context but the copy/move construction must be valid and the compiler doesn't have to perform the elision.
The a2
code is "guaranteed" as such and you should not get errors from that.