nanobind a vector of a NonCopyable class #712
-
Hello, I've pasted below the compilation message and a small reproducible example. If relevant, I'm using nanobind 2.1.0, and tried with gcc-11 or 12, python 3.10 or 3.12.
file my_binding.cpp#include <string>
#include <vector>
#include <nanobind/nanobind.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/bind_vector.h>
namespace nb = nanobind;
using namespace nb::literals;
/// A very big object
class Part {
public:
// no copy (it is a heavy object)
Part(const Part&) = delete;
Part& operator=(const Part&) = delete;
// move is ok
Part(Part&&) = default;
Part& operator=(Part&&) = default; // =delete
Part() = default;
~Part() = default;
Part(int /*very_big_size*/) { /*... create huge arrays here ...*/ }
protected:
// ... huge arrays ...
};
class MyContainer {
public:
// Part a_single_part; // this works fine
std::vector<Part> parts_;
};
NB_MODULE(mre1, m) {
m.doc() = "mre1 - a small binding.";
nb::class_<MyContainer>(m, "MyContainer")
.def(nb::init<>())
;
} CMakeLists.txtcmake_minimum_required(VERSION 3.20)
project(mre1)
set(DEV_MODULE Development.Module)
find_package(Python 3.8 COMPONENTS Interpreter ${DEV_MODULE} REQUIRED)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# Detect the installed nanobind package and import it into CMake
execute_process(
COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NB_DIR)
list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")
find_package(nanobind CONFIG REQUIRED)
nanobind_add_module(mre1 src/my_binding.cpp)
# Usage:
# cmake -S . -B build
# cmake --build build
# ( cd build ; python3 -c "import mre1; print(mre1.__doc__)" ) Thanks for any advices, |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
Perhaps bind_vector (you include the header, but you don't use it) with the |
Beta Was this translation helpful? Give feedback.
-
I had missed something in my design: the class MyContainer is naturally not copyable, but I forgot to explicitly delete the constructor. Adding The case for |
Beta Was this translation helpful? Give feedback.
I had missed something in my design: the class MyContainer is naturally not copyable, but I forgot to explicitly delete the constructor.
In pure C++, the copy-constructor is never called so the program compiles. Nanobind must be trying to instanciate a copy.
Adding
MyContainer(const MyContainer&) = delete;
fixes everything.The case for
a_single_part
works because the compiler implicitly deletes it for us.