Thread overview
Passing D reimplementation of C++ template as argument to a C++ function
Sep 24, 2022
Gregor Mückl
Sep 25, 2022
Nicholas Wilson
Oct 10, 2022
Gregor Mückl
September 24, 2022

Hi!

I have a D template struct that reimplements a C++ class template with identical memory layout for a set of types that matter to me. Now, I want to use some C++ functions and classes that use these template instances, from D. For that, I want to purposefully alias the D and C++ types. However, with the C++ type being templated, I don't know how to name that type in a extern declaration in D.

Consider, the following simplified example:

// C++ template class (from third party library)
template<typename T, typename X>
class Foo {
  // X is made part of the type as a behavior switch, but is never instanced
  T a, b;
};

using FooFloat = Foo<float>;

// own C++ function:
void bar(FooFloat f);

// D template struct
struct Foo(T) {
  T a, b;
}

alias FooFloat = Foo!float;

// How do I correctly bind the C++ function bar here?

Ideally, I want to pass an instance of the D implementation of FooFloat without introducing additional wrapper functions.

I know that the whole thing does sound quite mad at first glance and screams "bad idea!", but there is a reason why I want to try to tread into this minefield.

September 25, 2022

On Saturday, 24 September 2022 at 07:04:34 UTC, Gregor Mückl wrote:

>

Hi!

I have a D template struct that reimplements a C++ class template with identical memory layout for a set of types that matter to me. Now, I want to use some C++ functions and classes that use these template instances, from D. For that, I want to purposefully alias the D and C++ types. However, with the C++ type being templated, I don't know how to name that type in a extern declaration in D.

[...]

extern(C++) extern(C++, class) struct Foo(T) {
   T a, b;
}

alias FooFloat = Foo!float;

extern(C++) void bar(FooFloat f);
October 10, 2022

On Sunday, 25 September 2022 at 23:23:51 UTC, Nicholas Wilson wrote:

>

On Saturday, 24 September 2022 at 07:04:34 UTC, Gregor Mückl wrote:
extern(C++) extern(C++, class) struct Foo(T) {
T a, b;
}

alias FooFloat = Foo!float;

extern(C++) void bar(FooFloat f);

This works when you mirror all the template arguments in the correct order as they are part of the mangled name. Thanks!