pybind/pybind11

[BUG]: PYBIND11_NUMPY_DTYPE doesn't support templated types with multiple template arguments

Open

#4,018 opened on Jun 20, 2022

View on GitHub
 (2 comments) (0 reactions) (0 assignees)C++ (2,005 forks)batch import
bughelp wanted

Repository metrics

Stars
 (14,677 stars)
PR merge metrics
 (Avg merge 5d 2h) (10 merged PRs in 30d)

Description

Required prerequisites

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).

Contributor guide