pybind11
pybind11 copied to clipboard
[BUG]: PYBIND11_NUMPY_DTYPE doesn't support templated types with multiple template arguments
Required prerequisites
- [X] Make sure you've read the documentation. Your issue may be addressed there.
- [X] Search the issue tracker and Discussions to verify that this hasn't already been reported. +1 or comment there if it has.
- [X] Consider asking first in the Gitter chat room or in a Discussion.
Problem description
Compiler errors are thrown when using PYBIND11_NUMPY_DTYPE
with a struct with multiple template arguments. The errors are due to the comma in the template argument list causing the C++ preprocessor to expand the template arguments into extra macro arguments.
I am using pybind11 v2.9.2 and gcc 12.1
Reproducible example code
This code
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
template<typename T, typename U>
struct TestStruct {
T a;
int b;
U c;
};
PYBIND11_MODULE(numpy_dtype_test, pymodule) {
PYBIND11_NUMPY_DTYPE(TestStruct<float, double>, a, b, c);
}
Produces this error
pybind.cpp:14:5: error: wrong number of template arguments (1, should be 2)
14 | PYBIND11_NUMPY_DTYPE(TestStruct<float, double>, a, b, c);
Wrapping the first argument in parentheses doesn't help PYBIND11_NUMPY_DTYPE((TestStruct<float, double>), a, b, c);
. This produces error: template argument 1 is invalid
, I suspect because C++ doesn't like having the parentheses in the template argument (after the macro is expanded)
Using #define COMMA ,
and PYBIND11_NUMPY_DTYPE(TestStruct<float COMMA double>, a, b, c);
fails with error: wrong number of template arguments (1, should be 2)
. This fails in a slightly different way to the first error. The first expansion of TestStruct<float COMMA double>
works as desired, but subsequent expansion fail.
Using #define TEMPLATE_TYPE( ... ) __VA_ARGS__
and #define TEMPLATE_TYPE(A,B) A,B
with PYBIND11_NUMPY_DTYPE(TEMPLATE_TYPE(TestStruct<float, double>), a, b, c);
fail in similar way to #define COMMA ,
(but I think the point of failure is pushed slightly later in the macro expansion).
@Bidski As a workaround, you can try to create an alias TestStruct<float, double>
using the "using" keyword.
@Skylion007 you are correct, a using
alias does create a viable workaround