www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - default arguments for const ref parameters in extern C++ functions

reply 60rntogo <60rntogo gmail.com> writes:
I'm trying to use a C++ library that has a function declared like 
this:

---
struct Foo
{
   int x;
};

void fun(const Foo& foo = Foo(1));
---

I have translated this to a D declaration:

---
struct Foo
{
   int x;
}

extern(C++) void fun(const ref Foo foo = Foo(1));
---

This yields an error: "Foo(1) is not an lvalue and cannot be 
modified". I suppose this makes sense with how D references work, 
but I have no control over how the C++ function is declared. What 
can I do with this?
Sep 14 2020
next sibling parent 60rntogo <60rntogo gmail.com> writes:
On Monday, 14 September 2020 at 12:44:34 UTC, 60rntogo wrote:
 ---
 struct Foo
 {
   int x;
 }

 extern(C++) void fun(const ref Foo foo = Foo(1));
 ---
I suppose this should have been: --- extern(C++): struct Foo { int x; } void fun(const ref Foo foo = Foo(1)); --- Not that it changes the question in any way.
Sep 14 2020
prev sibling parent reply k2aj <krzysztof.jajesnica gmail.com> writes:
On Monday, 14 September 2020 at 12:44:34 UTC, 60rntogo wrote:
 I'm trying to use a C++ library that has a function declared 
 like this:

 ---
 struct Foo
 {
   int x;
 };

 void fun(const Foo& foo = Foo(1));
 ---

 I have translated this to a D declaration:

 ---
 struct Foo
 {
   int x;
 }

 extern(C++) void fun(const ref Foo foo = Foo(1));
 ---

 This yields an error: "Foo(1) is not an lvalue and cannot be 
 modified". I suppose this makes sense with how D references 
 work, but I have no control over how the C++ function is 
 declared. What can I do with this?
AFAIK the only way to have default ref arguments is to use a global variable: --- extern(C++) struct Foo { int x; } immutable foo1 = Foo(1); extern(C++) void fun(const ref Foo foo = foo1); ---
Sep 14 2020
parent reply 60rntogo <60rntogo gmail.com> writes:
On Monday, 14 September 2020 at 17:11:59 UTC, k2aj wrote:
 AFAIK the only way to have default ref arguments is to use a 
 global variable:
 ---
 extern(C++) struct Foo
 {
   int x;
 }
 immutable foo1 = Foo(1);
 extern(C++) void fun(const ref Foo foo = foo1);
 ---
Thanks. This appears to work, but feels like a hack. I can live with that, but I'm still wondering if there is a more idiomatic way of solving the problem.
Sep 14 2020
parent Mathias LANG <geod24 gmail.com> writes:
On Monday, 14 September 2020 at 18:58:44 UTC, 60rntogo wrote:
 On Monday, 14 September 2020 at 17:11:59 UTC, k2aj wrote:
 AFAIK the only way to have default ref arguments is to use a 
 global variable:
 ---
 extern(C++) struct Foo
 {
   int x;
 }
 immutable foo1 = Foo(1);
 extern(C++) void fun(const ref Foo foo = foo1);
 ---
Thanks. This appears to work, but feels like a hack. I can live with that, but I'm still wondering if there is a more idiomatic way of solving the problem.
D doesn't let rvalues bind to const ref (well, `in` will do that, but it's D-only). What was described as "global variable", is more of a "manifest constant lvalue". A (static) immutable variable with an initializer will always be CTFE-d and available at compile time, so in this case it is *exactly* what you need. Also note that a default parameter doesn't affect the mangling / ABI, because it works exclusively on the caller side. Thus, you could just remove the default argument and your `extern(C++)` binding would work just fine. But if you want to provide the same API, `[static] immutable` + initializer is the way to go.
Sep 14 2020