Jump to page: 1 2
Thread overview
Template error on compiling ...
Feb 28, 2014
Robin
Feb 28, 2014
Tobias Pankrath
Feb 28, 2014
anonymous
Feb 28, 2014
Robin
Feb 28, 2014
anonymous
Feb 28, 2014
Robin
Feb 28, 2014
anonymous
Feb 28, 2014
Robin
Feb 28, 2014
Ali Çehreli
Feb 28, 2014
Robin
Mar 01, 2014
Stanislav Blinov
Mar 01, 2014
Meta
Mar 01, 2014
Robin
February 28, 2014
Hiho,

I am currently working on a matrix library (matrices are templated structs) and have just implemented so-called "ElementalOperations" which perform certain tasks on mutable matrices.

There is an abstract ElementalOperation where three different ElementalOperation types inherit from. These ElementalOperations are structured like that:

module neoLab.core.ScaleRowOperation;

import neoLab.core.ElementalOperation;
import neoLab.core.Matrix;

final class ScaleRowOperation(T = double) : ElementalOperation
	if (!hasIndirections!T)
{
	private
	{
		size_t row = 0;
		T factor = 1;
	}

	this(size_t row, T factor) pure nothrow {
		this.row = row;
		this.factor = factor;
	}

	override void opCall(ref Matrix m) pure nothrow {
		foreach (immutable col; 0 .. m.getDimension().cols) {
			m[this.row, col] *= this.factor;
		}
	}

	override string toString() const pure nothrow {
		return "Scale all elements of row " ~ this.row ~
				" by factor " ~ this.factor ~ ".";
	}
}

So it is a fairly simple concept until now and I haven't spend time on improving its performance as I run into a strange compiler error, telling me the following:

neoLab/core/ElementalOperation.d(6): Error: struct neoLab.core.Matrix.Matrix(T = double) if (!hasIndirections!T) is used as a type
neoLab/core/SwapRowsOperation.d(18): Error: struct neoLab.core.Matrix.Matrix(T = double) if (!hasIndirections!T) is used as a type

The matrix struct is defined as follows:

struct Matrix(T = double) if (!hasIndirections!T)

In the documentation hasIndirections!T reads:
Returns true if and only if T's representation includes at least one of the following:
    - a  raw pointer U*;
    - an array U[];
    - a  reference to a class type C.
    - an associative array.
    - a  delegate.

I don't know why this error occures at all. In my opinion it shouldn't, or am I doing something wrong again?

Thanks in advance for help. =)

Robin
February 28, 2014
On Friday, 28 February 2014 at 19:09:11 UTC, Robin wrote:
>
> 	override void opCall(ref Matrix m) pure nothrow {
> 		foreach (immutable col; 0 .. m.getDimension().cols) {
> 			m[this.row, col] *= this.factor;
> 		}

I guess this is the culprit. You must use Matrix!(). In general if the compiler says that "X is used as type", where X is something like a template, than you are using the template X instead of an instance where you should not.

There is probably an enhancement request to make the code above legal, though.


February 28, 2014
On Friday, 28 February 2014 at 19:16:11 UTC, Tobias Pankrath
wrote:
> On Friday, 28 February 2014 at 19:09:11 UTC, Robin wrote:
>>
>> 	override void opCall(ref Matrix m) pure nothrow {
>> 		foreach (immutable col; 0 .. m.getDimension().cols) {
>> 			m[this.row, col] *= this.factor;
>> 		}
>
> I guess this is the culprit. You must use Matrix!(). In general if the compiler says that "X is used as type", where X is something like a template, than you are using the template X instead of an instance where you should not.
>
> There is probably an enhancement request to make the code above legal, though.

Here it should probably be Matrix!T, though.
February 28, 2014
Hiho,

both

opCall(ref Matrix!() m)

opCall(ref Matrix!T m)

aswell as

opCall(ref Matrix!(m))

or just

opCall(ref Matrix m)

give me all the same error as the one stated in the first post ... :/

Nothing really seems to work here.

Robin
February 28, 2014
On Friday, 28 February 2014 at 19:33:17 UTC, Robin wrote:
> opCall(ref Matrix!() m)
>
> opCall(ref Matrix!T m)
>
> aswell as
>
> opCall(ref Matrix!(m))

This one's just nonsense.

> or just
>
> opCall(ref Matrix m)

This one gives you the "used as a type" kind of error message.

> give me all the same error as the one stated in the first post ... :/

You're probably looking in the wrong place (for that particular
error message).

neoLab/core/ElementalOperation.d, line 6, and
neoLab/core/SwapRowsOperation.d, line 18,
are the spots the compiler complains about (so far).

> module neoLab.core.ScaleRowOperation;
suggests that you're looking at neither of those two files. You still have to fix it there, too, though.
February 28, 2014
Hiho,

with

import neoLab.core.Matrix;

abstract class ElementalOperation(T = double) {
    abstract void opCall(ref Matrix!T m);
    abstract override string toString();
}

where I have made the abstract class templated "(T = double)" and where I have added a "!T" after "Matrix" in the opCall parameter list I get the following error:

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
--- errorlevel 1

When I leave the (T = double) template assignment out I get another error:

neoLab/core/ElementalOperation.d(6): Error: undefined identifier T

With Tobias Pankrath's Matrix!() I get the following linker error:

/usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
ScaleRowOperation.o: In function

.... many many many lines of unuseful error messages ...

(.text._D6neoLab4core6Matrix11__T6MatrixZ6Matrix6randomFxmxmdddZS6neoLab4core6Matrix11__T6MatrixZ6Matrix+0x145): undefined reference to `_D6neoLab4core9Dimension9Dimension4sizeMxFNaNbNdZm'
collect2: error: ld returned 1 exit status
--- errorlevel 1

So, in conclusion. I still have no clue why this more or less simple construct does not work but gives me errors on compiling.

Robin
February 28, 2014
On Friday, 28 February 2014 at 20:54:42 UTC, Robin wrote:
> Hiho,
>
> with
>
> import neoLab.core.Matrix;
>
> abstract class ElementalOperation(T = double) {
>     abstract void opCall(ref Matrix!T m);
>     abstract override string toString();
> }
>
> where I have made the abstract class templated "(T = double)" and where I have added a "!T" after "Matrix" in the opCall parameter list I get the following error:
>
> /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o: In function `_start':
> (.text+0x20): undefined reference to `main'
> collect2: error: ld returned 1 exit status
> --- errorlevel 1

The error message is unrelated. "undefined reference to `main'"
-> no main function. You can add -main to your dmd invocation to
let the compiler generate a dummy main.

> When I leave the (T = double) template assignment out I get another error:
>
> neoLab/core/ElementalOperation.d(6): Error: undefined identifier T

Well, sure, you just removed T.

> With Tobias Pankrath's Matrix!() I get the following linker error:
>
> /usr/lib/gcc/x86_64-unknown-linux-gnu/4.8.2/../../../../lib/crt1.o: In function `_start':
> (.text+0x20): undefined reference to `main'

Same as above: no main function.

> ScaleRowOperation.o: In function
>
> .... many many many lines of unuseful error messages ...
>
> (.text._D6neoLab4core6Matrix11__T6MatrixZ6Matrix6randomFxmxmdddZS6neoLab4core6Matrix11__T6MatrixZ6Matrix+0x145): undefined reference to `_D6neoLab4core9Dimension9Dimension4sizeMxFNaNbNdZm'
> collect2: error: ld returned 1 exit status
> --- errorlevel 1

Can't say much about this. Might just be fallout from previous
failures.

> So, in conclusion. I still have no clue why this more or less simple construct does not work but gives me errors on compiling.

Matrix!T is the way to go.
February 28, 2014
Hiho,

aww, that's a noob mistake of me.

Thanks!

Should take a closer look at the error messages next time a should think more about their special meaning ...

It works now while it feels strange that I have to template the three classes as I am only working with references to matrix and in my understanding this shouldn't affect the compilate. But, well, in the end it works now.^^

Robin
February 28, 2014
On 02/28/2014 02:21 PM, Robin wrote:

> I am only working with references to matrix and in my understanding this
> shouldn't affect the compilate.

As I understand it, Matrix is not a type; rather a type template. Only instances of that template like Matrix!double can be used as types.

I was interested in this thread but I could not put pieces together in my mind without complete code. Could you please demonstrate the problem with minimal code next time. Thanks. :)

Ali

February 28, 2014
Hiho,

just for you: the whole code! =)
http://dpaste.dzfl.pl/cd1537571a4d

The idea is that I have matrix instances and so-called ElementalOperations which are able to operate on matrices to solve certain algorithms object oriented without nasty loops and so on.

This had worked perfectly in my java implementation so far.

Robin
« First   ‹ Prev
1 2