#include <charconv>
#include <future>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
#include <variant>
#include <vector>
#include <unordered_set>
#include <span>
struct MyStruct {
std::unordered_set<int> s;
MyStruct() {
std::cout << "constructor\n";
}
MyStruct(const MyStruct& other) {
std::cout << "copy constructor\n";
this->s = other.s;
}
MyStruct& operator=(const MyStruct& other) {
std::cout << "copy assignment\n";
this->s = other.s;
return *this;
}
MyStruct(MyStruct&& other) {
std::cout << "move constructor\n";
this->s = other.s;
}
MyStruct& operator=(MyStruct&& other) {
std::cout << "move assignment\n";
this->s = std::move(other.s);
return *this;
}
};
struct Holder {
Holder() : structs{MyStruct(), MyStruct()} {}
const std::vector<MyStruct> structs;
};
void PrintStructs(std::span<const MyStruct> my_structs)
{
for (const MyStruct& s : my_structs) {
std::cout << "iterate on a struct\n";
}
}
int main()
{
Holder holder;
std::cout << "holder created\n";
PrintStructs(holder.structs);
return 0;
}
Consider the above code. PrintStructs
will not copy structs at all but still guarantee the constness of MyStruct
Constness is especially important. Consider the following awkward situation when you deal with vector of pointers.
struct Foo {
void SomeNonConstOp() {}
};
class MyClass {
public:
// This is supposed to be const.
// Don’t modify my Foos, pretty please.
const std::vector<Foo*>& shallow_foos() const { return foos_; }
// Really deep const.
std::span<const Foo* const> deep_foos() const { return foos_; }
// Does not compile
// main.cpp:74:34: error: ‘const std::vector& MyClass::shallow_foos() const’ cannot be overloaded with ‘const std::vector& MyClass::shallow_foos() const’
// const std::vector<const Foo*>& shallow_foos() const { return foos_; }
private:
std::vector<Foo*> foos_;
};
void Caller(const MyClass* my_class) {
// Accidental violation of MyClass::shallow_foos() contract.
my_class->shallow_foos()[0]->SomeNonConstOp();
// This one doesn't compile.
// my_class->deep_foos()[0]->SomeNonConstOp();
}