Concrete types
Created by: gcarleo
This PR re-establishes the usage of concrete types for Machine
, Graph
etc, removing the interim usage of std::shared_ptr
that was dictated by the pybind11 interface rather than NetKet design.
Concrete types are based on std::variant
(actually a non-standard version backported to c++14).
This effectively moves NetKet from C++11 to C++14, which seems a reasonable move, given the current development of the compilers. Moving to C++17 is too premature because of sparse support for std::variant
std::optional
etc, especially on Mac platforms.
Using std::variant
should (maybe) also help a little bit with performance (to be seen).
Working with concrete types also has many advantages when implementing python pickling.
I am not entirely satisfied by this implementation because I wasn't able to define copy constructors for the concrete types, because of some obscure variant-related issue. Any help with this is much appreciated.
The variant-based polymorphism is obtained like this:
class Hilbert : public AbstractHilbert {
public:
using VariantType = mpark::variant<Spin, Boson, Qubit, CustomHilbert>;
private:
VariantType obj_;
public:
Hilbert(VariantType obj) : obj_(obj) {}
bool IsDiscrete() const override {
return mpark::visit([](auto &&obj) { return obj.IsDiscrete(); }, obj_);
}
.....
Since we are working with objects, it would be useul also to use more thoroughly std::move
than what I already did.