As a follow-up question to Using cppyy with rvalue pointers and maps (Apologies for not coming up with a simpler example)
I am attempted to initialize a NameToBasisModel(std::map<std::string, std::unique_ptr<Basis<TBasisTemplateType>>>&& nameToBasisMap)
from cppyy
. I am not sure how to construct an object that takes in a map of unique_ptrs
of templated, custom classes since cppyy
seems to treat pointers and objects identically.
In the C++ code, the call looks like this:
// use the PSDs from the output of LALInferenceReadData to fill the FixedNoiseModelComponent
std::map<std::string, std::unique_ptr<Basis<PowerSpectrumDensity>>> nameToBasisMap;
for (const auto& [interferometerName, interferometer] : data_->getInterferometerNameToInterferometerMap()) {
PowerSpectrumDensity powerSpectrumDensity{interferometer.powerSpectrumDensity.value()};
const std::string identifier = "fixed noise basis for " + interferometerName;
auto basis = std::make_unique<FixedBasis<PowerSpectrumDensity>>(identifier, std::move(powerSpectrumDensity),
PowerSpectrumDensity{powerSpectrumDensity.getSegmentLengthSec(), powerSpectrumDensity.getSamplingRateHz()});
nameToBasisMap.emplace(interferometerName, std::move(basis));
}
auto noiseModel = std::make_unique<NameToBasisModel<PowerSpectrumDensity>>(std::move(nameToBasisMap));
To make my map I first tried:
# make noise model
nameToBasisMap = Cpp.std.map[Cpp.std.string, Cpp.Basis[Cpp.PowerSpectrumDensity]]()
for interferometerName, interferometer in self.data.getInterferometerNameToInterferometerMap():
print(interferometerName, interferometer)
powerSpectrumDensity = Cpp.PowerSpectrumDensity(interferometer.powerSpectrumDensity.value())
identifier = "fixed noise basis for " + interferometerName
basis = Cpp.FixedBasis[Cpp.PowerSpectrumDensity](
identifier,
Cpp.std.move(powerSpectrumDensity),
Cpp.std.move(Cpp.PowerSpectrumDensity(powerSpectrumDensity.getSegmentLengthSec(),
powerSpectrumDensity.getSamplingRateHz()))
)
nameToBasisMap.emplace(interferometerName, Cpp.std.move(basis))
However, this failed when making the map (which isn't surprising, Basis itself is not implemented.)
(Here is part of the long traceback, but it is failing when trying to call emplace)
map<std::string,Basis<PowerSpectrumDensity> >::map<std::string,Basis<PowerSpectrumDensity> >(const std::map<std::string,Basis<PowerSpectrumDensity> >::allocator_type& __a) =>
TypeError: takes at least 1 arguments (0 given)
map<std::string,Basis<PowerSpectrumDensity> >::map<std::string,Basis<PowerSpectrumDensity> >(const std::map<std::string,Basis<PowerSpectrumDensity> >& __m, const std::map<std::string,Basis<PowerSpectrumDensity> >::allocator_type& __a) =>
TypeError: takes at least 2 arguments (0 given)
std::map<std::string,Basis<PowerSpectrumDensity> > constructor failed
map<std::string,Basis<PowerSpectrumDensity> >::map<std::string,Basis<PowerSpectrumDensity> >(const std::map<std::string,Basis<PowerSpectrumDensity> >& __m) =>
TypeError: takes at least 1 arguments (0 given)
Failed to instantiate "map<std::string,Basis<PowerSpectrumDensity> >()"
I then tried replacing nameToBasisMap = Cpp.std.map[Cpp.std.string, Cpp.Basis[Cpp.PowerSpectrumDensity]]()
with the subclass nameToBasisMap = Cpp.std.map[Cpp.std.string, Cpp.FixedBasis[Cpp.PowerSpectrumDensity]]()
Which creates the map without complaint. However when I try to construct the NameToBasisModel
noiseModel = Cpp.NameToBasisModel[Cpp.PowerSpectrumDensity](Cpp.std.move(nameToBasisMap))
it segfaults.
I also tried to replace it with
nameToBasisMap = Cpp.std.map[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Basis[Cpp.PowerSpectrumDensity]]]()
which also crashes.
What am I doing wrong? How can I construct something that explicitly uses pointers in a type?