Pybind11: pybind::vector doesnt compile with VS 15.9.x

Created on 21 Nov 2018  路  11Comments  路  Source: pybind/pybind11

Issue description

Simple pybind::vector usage doesn't compile with VS 15.9.x
PYBIND11_MAKE_OPAQUE(std::vector);
...
py::bind_vector(m, "BoolList");

stl_bind.h(386): error C2672: 'pybind11::detail::vector_buffer': no matching overloaded function found
core_submodule.cpp(19): note: see reference to function template instantiation 'pybind11::class_>,std::unique_ptr>>>> pybind11::bind_vector>,std::unique_ptr>>>,>(pybind11::handle,const std::string &)' being compiled
with
[
_Ty=bool,
Vector=std::vector>
]
include\pybind11\stl_bind.h(374): error C2893: Failed to specialize function template 'enable_if<_Test,_Ty>::type pybind11::detail::vector_buffer(Class_ &)'
with
[
_Ty=void
]
\include\pybind11\stl_bind.h(374): note: With the following template arguments:
\include\pybind11\stl_bind.h(374): note: 'Vector=Vector'
\include\pybind11\stl_bind.h(374): note: 'Class_=Class_'
\include\pybind11\stl_bind.h(374): note: 'Args={}'

Reproducible example code

PYBIND11_MAKE_OPAQUE(std::vector);

...
py::bind_vector>(m, "BoolList");

(The code should be minimal, have no external dependencies, isolate the function(s) that cause breakage. Submit matched and complete C++ and Python snippets that can be easily compiled and run to diagnose the issue.)

Most helpful comment

I ran into the same issue,

For some unknown reason VS refuses to find this definition, even though there are now "buffer_protocol" tag types in the args list. If one does use "buffer_protocol" it works...

https://github.com/pybind/pybind11/blob/e2b884c33bcde70b2ea562ffa52dd7ebee276d50/include/pybind11/stl_bind.h#L365-L366

also just using

    if constexpr(detail::any_of<std::is_same<Args, buffer_protocol>...>::value) {
        detail::vector_buffer<Vector, Class_, Args...>(cl);
    }

instead of
https://github.com/pybind/pybind11/blob/e2b884c33bcde70b2ea562ffa52dd7ebee276d50/include/pybind11/stl_bind.h#L386

also works fine...

All 11 comments

I ran into the same issue,

For some unknown reason VS refuses to find this definition, even though there are now "buffer_protocol" tag types in the args list. If one does use "buffer_protocol" it works...

https://github.com/pybind/pybind11/blob/e2b884c33bcde70b2ea562ffa52dd7ebee276d50/include/pybind11/stl_bind.h#L365-L366

also just using

    if constexpr(detail::any_of<std::is_same<Args, buffer_protocol>...>::value) {
        detail::vector_buffer<Vector, Class_, Args...>(cl);
    }

instead of
https://github.com/pybind/pybind11/blob/e2b884c33bcde70b2ea562ffa52dd7ebee276d50/include/pybind11/stl_bind.h#L386

also works fine...

Also just switching to

template <typename Vector, typename Class_, typename... Args>
typename std::enable_if<!detail::any_of<std::is_same<Args, buffer_protocol>...>::value>::type vector_buffer(Class_&) {}

makes it compile again :(

just adding an extra doc string also makes it compile for me:

py::bind_vector<std::vector<bool>>(m, "BoolList", "doc string");

Love when the compiler is so stable and predictable ;)

The following works:

  py::bind_vector< std::vector< std::string > >( mod, "StringVector" );

Are you 100% sure passing std::vector instead of std::vector< somthing > is correct?

Humm In my cast the "Something" was a glm vec type... and yes I use std::vector< somthing >, the other one with just std::vector, must be wrong in this context.

But no I think there might be an other issue at play here, std::vector is a special vector type... that might not play so nicely with pybind11...

I'm using quite a bit of std::vectors from python and it all works just fine once the "something" has appropriate binding. This issue, to me, really looks like a user error.

Are you using VS 15.9.2 or newer?

py::bind_vector>(m, "somelist", "description"); WORKS
py::bind_vector>(m, "somelist"); DOESNT WORK

Well, the Appveyor is running some version of MSVC 2017, but it looks like it is running 14.15.26726.

Are you using VS 15.9.2 or newer?

py::bind_vector>(m, "somelist", "description"); WORKS
py::bind_vector>(m, "somelist"); DOESNT WORK

I have the exact same behaviour,
Im running VS 15.9.3.

Did use to work before, must be some kind of compiler regression...

Can't reproduce with VS 2017, MSVC 19.16.27041.0, Microsoft (R) Build Engine version 15.9.21+g9802d43bc3, for pybind11 2.5.0, and this code:

#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

namespace py = pybind11;

PYBIND11_MAKE_OPAQUE(std::vector<std::string>);
PYBIND11_MAKE_OPAQUE(std::vector<bool>);

PYBIND11_MODULE(example, m) {
    py::bind_vector<std::vector<std::string>>(m, "StringVector");
    py::bind_vector<std::vector<bool>>(m, "BoolVector");
}

Maybe something got fixed? @vdolbakyan @petersteneteg Is this still an issue? If so, would you mind providing a complete minimal example, such that I can investigate? Please reopen if so.

With C++17 (/std:c++17), to get MSVC to behave, you need /permissive-. You should probably be compiling with that flag all the time, as it makes MSVC more strictly conforming.

EDIT: References: https://github.com/pybind/pybind11/issues/2089 and https://github.com/pybind/pybind11/pull/2292

Was this page helpful?
0 / 5 - 0 ratings