Missing Symbol Accessing Templated Function Through Interface

2016-03-08 Thread Peter via Digitalmars-d-learn

Hi,

Can anyone explain to me what's causing the following code to 
generate a missing symbol error...


import std.stdio;

interface IProblem {
   void writeln(T...)(T arguments);
}

class Problem : IProblem {
   void writeln(T...)(T arguments) {
  // This is just here to have code in an implementation.
  stdout.writeln("The implementation function was called.");
   }
}

IProblem getProblem() {
   return(new Problem());
}

void main() {
   auto problem = getProblem();

   problem.writeln("Some text and a number - ", 1234);
}

Now obviously this codes a bit contrived but its my attempt to 
reduce an issue I'm seeing to its more concise form. Note that if 
I cast the return value from the call to getProblem() to a 
Problem instance this rectifies the issue but I'm unclear as to 
why this might be. The error I get when I compile this is...


   Undefined symbols for architecture x86_64:
 "_D3app8IProblem18__T7writelnTAyaTiZ7writelnMFAyaiZv", 
referenced from:

 __Dmain in template_issue.o
   ld: symbol(s) not found for architecture x86_64
   clang: error: linker command failed with exit code 1 (use -v 
to see invocation)

   --- errorlevel 1
   dmd failed with exit code 1.

Apologies is the cause is blatantly obvious to more experienced D 
coders.


Regards,

Peter


Re: Missing Symbol Accessing Templated Function Through Interface

2016-03-08 Thread Peter via Digitalmars-d-learn

On Tuesday, 8 March 2016 at 12:24:06 UTC, crimaniak wrote:

On Tuesday, 8 March 2016 at 11:50:32 UTC, Peter wrote:

Hi,

Can anyone explain to me what's causing the following code to 
generate a missing symbol error...


Relevant comment: 
https://issues.dlang.org/show_bug.cgi?id=8553#c1


Thanks for link, makes sense.


Array operations with array of structs

2015-07-05 Thread Peter via Digitalmars-d-learn

Hi,
I have a struct with arithmetic operations defined using opBinary 
but array operations with arrays of it don't work.


struct Vector3 {
public double[3] _p;
...
Vector3 opBinary(string op)(in Vector3 rhs) const
if (op == "+"){
Vector3 result;
result._p[] = this._p[] + rhs._p[];
return result;
}
...
}

unittest{
auto a = Vector3([2.0, 2.0, 0.0]);
auto b = Vector3([1.0, 2.0, 1.0]);
Vector3[] c = [a];
Vector3[] d = [b];
Vector3 e = a + b; // works
Vector3[] f;
f[] = c[] + d[]; // Error: invalid array operation 'f[] = c[] 
+ d[]' because Vector3 doesn't support necessary arithmetic 
operations

}

how can I get this to work?

Thanks



Re: Array operations with array of structs

2015-07-06 Thread Peter via Digitalmars-d-learn

On Monday, 6 July 2015 at 10:29:35 UTC, anonymous wrote:
Works for me with various versions of dmd on linux. What 
compiler are you using, what version of it, what operating 
system, etc?


dmd 2.066.1, windows 7 64bit


Re: Array operations with array of structs

2015-07-07 Thread Peter via Digitalmars-d-learn

On Monday, 6 July 2015 at 15:48:28 UTC, anonymous wrote:

Ok, I disabled everything in the struct except what I posted and 
it ran.
I then uncommented stuff to isolate the cause. I've added in the 
bits that cause the error below (plus some constructors just for 
reference).


struct Vector3 {
public double[3] _p;
@nogc this(in double[] p)
{
switch ( p.length ) {
case 0: _p[0] = _p[1] = _p[2] = 0.0; break;
case 1: _p[0] = p[0]; _p[1] = _p[2] = 0.0; break;
case 2: _p[0] = p[0]; _p[1] = p[1]; _p[2] = 0.0; break;
default: _p[0] = p[0]; _p[1] = p[1]; _p[2] = p[2]; break;
}
}
@nogc this(in double p0, in double p1=0.0, in double p2=0.0)
{
_p[0] = p0;
_p[1] = p1;
_p[2] = p2;
}
@nogc this(in Vector3 other)
{
_p[] = other._p[];
}
//...
Vector3 opBinary(string op)(in Vector3 rhs) const
if (op == "+"){
Vector3 result;
result._p[] = this._p[] + rhs._p[];
return result;
}
// The bits that cause the error:
//... Enabling any one (or more) of the following causes the 
error

this(this)
{
_p = _p.dup;
}

@nogc ref Vector3 opAssign(ref Vector3 rhs)
{
_p[] = rhs._p[];
 return this;
}

@nogc ref Vector3 opAssign(Vector3 rhs)
{
_p[] = rhs._p[];
return this;
}
//...
}

Any ideas about what's happening?


Re: Array operations with array of structs

2015-07-11 Thread Peter via Digitalmars-d-learn

On Wednesday, 8 July 2015 at 06:05:54 UTC, ketmar wrote:
do you see the gotcha? if you uncomment postblit or assigns, 
this build function fails to compile, as that operations aren't 
"pure nothrow @nogc @trusted", and they will be used for either 
assign or postblitting.


So after looking into it a little bit...

It looks like the opAssigns can take all the attributes without 
throwing errors so that's good.


The postblit can only not take @nogc due to the array duplication 
which is understandable.
I think the postblit might be redundant anyway since the struct 
is built on a static array so there is no possibility of two 
different Vect3s "pointing" to the same data.

Can someone confirm or does the postblit do anything else?



Re: Array operations with array of structs

2015-07-11 Thread Peter via Digitalmars-d-learn

On Saturday, 11 July 2015 at 13:31:12 UTC, Peter wrote:

So after looking into it a little bit...


So now I'm trying to multiply the array by a double but it's 
giving incompatible type errors. opBinary, opBinaryRight, and 
opOpAssign are defined.


I have:
struct Vector3 {
public double[3] _p;
@nogc this(in double[] p){
switch ( p.length ) {
case 0: _p[0] = _p[1] = _p[2] = 0.0; break;
case 1: _p[0] = p[0]; _p[1] = _p[2] = 0.0; break;
case 2: _p[0] = p[0]; _p[1] = p[1]; _p[2] = 0.0; break;
default: _p[0] = p[0]; _p[1] = p[1]; _p[2] = p[2]; break;
}
}
@nogc this(in double p0, in double p1=0.0, in double p2=0.0){
_p[0] = p0;
_p[1] = p1;
_p[2] = p2;
}
@nogc this(in Vector3 other){
_p[] = other._p[];
}
Vector3 opBinary(string op)(in Vector3 rhs) const
if (op == "+")
{
Vector3 result;
result._p[] = this._p[] + rhs._p[];
return result;
}
Vector3 opBinary(string op)(in double rhs) const
if (op == "*")
{
Vector3 result;
result._p[] = this._p[] * rhs;
return result;
}
Vector3 opBinaryRight(string op)(in double lhs) const
if (op == "*")
{
Vector3 result;
result._p[] = this._p[] * lhs;
return result;
}
//...
pure nothrow @trusted @nogc ref Vector3 opAssign(ref Vector3 
rhs)

{
_p[] = rhs._p[];
return this;
}
pure nothrow @trusted @nogc ref Vector3 opAssign(Vector3 rhs)
{
_p[] = rhs._p[];
return this;
}
@nogc ref Vector3 opOpAssign(string op)(in double rhs)
if (op == "*")
{
this._p[] *= rhs;
return this;
}
//...
}
unittest{
auto a = Vector3([2.0, 2.0, 0.0]);
auto b = Vector3([1.0, 2.0, 1.0]);
Vector3[] c = [a];
Vector3[] d = [b];
Vector3 e = a + b; //fine
Vector3[] f;
f[] = c[] + d[]; //fine

e = 2*a; //fine
e = 3.0*a; //fine
f[] = 2*c[]; //Error: incompatible types for ((2) * (c[])): 
'int' and 'Vector3[]'
f[] = 3.0*c[]; //Error: incompatible types for ((3.0) * 
(c[])): 'double' and 'Vector3[]'

}