Skip to content

binding std::vector of non copy/move-constructible elements #487

Closed
@albertziegenhagel

Description

@albertziegenhagel

The following code fails to compile (tested with VS 2015 Update 3 and Apple LLVM version 8.0.0, which should be clang ~3.8):

class El2
{
public:
    El2(const El2&) = delete;
    El2& operator=(const El2&) = delete;
};

py::bind_vector<std::vector<El>>(m, "VectorEl");

This is because the tests in

#if !defined(_MSC_VER)
/* Only enabled when the types are {copy,move}-constructible *and* when the type
does not have a private operator new implementaton. */
template <typename T = type> static auto make_copy_constructor(const T *value) -> decltype(new T(*value), Constructor(nullptr)) {
return [](const void *arg) -> void * { return new T(*((const T *) arg)); }; }
template <typename T = type> static auto make_move_constructor(const T *value) -> decltype(new T(std::move(*((T *) value))), Constructor(nullptr)) {
return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *) arg))); }; }
#else
/* Visual Studio 2015's SFINAE implementation doesn't yet handle the above robustly in all situations.
Use a workaround that only tests for constructibility for now. */
template <typename T = type, typename = enable_if_t<std::is_copy_constructible<T>::value>>
static Constructor make_copy_constructor(const T *value) {
return [](const void *arg) -> void * { return new T(*((const T *)arg)); }; }
template <typename T = type, typename = enable_if_t<std::is_move_constructible<T>::value>>
static Constructor make_move_constructor(const T *value) {
return [](const void *arg) -> void * { return (void *) new T(std::move(*((T *)arg))); }; }
#endif
check whether the vector is copy/move-constructible only, but not whether the element stored in the vector is copy/move-constructible as well. In the current C++ standard std::vector has a copy/move constructor even if it's value type is not copy/move constructible.

See http://stackoverflow.com/questions/18404108/issue-with-is-copy-constructible for some discussion, and a possible workaround, about that topic.

Please note that this may be of special interest because std::vector<std::unique_ptr<T>> is never copy-constructible but may be a common use case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions