www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template bug with second mixin?

reply "Andre" <andre s-e-a-p.de> writes:
Hi,

following coding fails to compile with 2.066.0 and
2.067.0-b1.


This is a bug, or?
source\app.d(9): Error: mixin 
app.Data.insertReadMethods!("readTinyInt", ubyte)
is not defined

template insertReadMethods(string MethodName, DataType)
{
	enum insertReadMethods = "";
}

struct Data
{
	mixin insertReadMethods!("readTinyInt", ubyte);
	mixin insertReadMethods!("readTinyInt", ubyte);
}

void main(){}

Kind regards
André
Dec 04 2014
next sibling parent ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Fri, 05 Dec 2014 07:06:34 +0000
Andre via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Hi,
=20
 following coding fails to compile with 2.066.0 and
 2.067.0-b1.
=20
=20
 This is a bug, or?
 source\app.d(9): Error: mixin=20
 app.Data.insertReadMethods!("readTinyInt", ubyte)
 is not defined
=20
 template insertReadMethods(string MethodName, DataType)
 {
 	enum insertReadMethods =3D "";
 }
=20
 struct Data
 {
 	mixin insertReadMethods!("readTinyInt", ubyte);
 	mixin insertReadMethods!("readTinyInt", ubyte);
 }
=20
 void main(){}
not a bug. what you doing is actually: struct Data { enum insertReadMethods =3D ""; mixin insertReadMethods!("readTinyInt", ubyte); } `enum insertReadMethods` is definitely not a template, and compiler correctly tells that to you.
Dec 04 2014
prev sibling parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Fri, 05 Dec 2014 07:06:34 +0000
Andre via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 Hi,
=20
 following coding fails to compile with 2.066.0 and
 2.067.0-b1.
=20
=20
 This is a bug, or?
 source\app.d(9): Error: mixin=20
 app.Data.insertReadMethods!("readTinyInt", ubyte)
 is not defined
=20
 template insertReadMethods(string MethodName, DataType)
 {
 	enum insertReadMethods =3D "";
 }
=20
 struct Data
 {
 	mixin insertReadMethods!("readTinyInt", ubyte);
 	mixin insertReadMethods!("readTinyInt", ubyte);
 }
=20
 void main(){}
i.e. "mixin template" inserts it's names into the same scope, and compiler searching symbols from innermost scope up to module scope. here first mixin inserts 'enum' member, and searching for second mixin hits that enum member. to avoid things going out of control compiler is not trying to guess what you want but stops with error, giving you a chance to fix the code.
Dec 04 2014
parent reply "Andre" <andre s-e-a-p.de> writes:
I think I mimized the coding too much.
What I actually want to achieve is to generate read methods
in the structure for different data types  (Ubyte, short, int):

I thought the eponymous trick would insert the content of the
enum instead the name itself?

string getReadMethods(string methodName, string dataType)
{
   return dataType~` `~methodName~`(size_t idx) {
     return v_arr[idx].get!`~dataType~`; }`;
}

template insertReadMethods(string MethodName, DataType)
{
   enum insertReadMethods = getReadMethods(MethodName, 
DataType.stringof);
}

struct Data
{
	mixin insertReadMethods!("readTinyInt", ubyte);
	mixin insertReadMethods!("readShortInt", short);
}

void main(){}


Kind regards
André

On Friday, 5 December 2014 at 07:28:26 UTC, ketmar via 
Digitalmars-d-learn wrote:
 On Fri, 05 Dec 2014 07:06:34 +0000
 Andre via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com> wrote:

 Hi,
 
 following coding fails to compile with 2.066.0 and
 2.067.0-b1.
 
 
 This is a bug, or?
 source\app.d(9): Error: mixin 
 app.Data.insertReadMethods!("readTinyInt", ubyte)
 is not defined
 
 template insertReadMethods(string MethodName, DataType)
 {
 	enum insertReadMethods = "";
 }
 
 struct Data
 {
 	mixin insertReadMethods!("readTinyInt", ubyte);
 	mixin insertReadMethods!("readTinyInt", ubyte);
 }
 
 void main(){}
i.e. "mixin template" inserts it's names into the same scope, and compiler searching symbols from innermost scope up to module scope. here first mixin inserts 'enum' member, and searching for second mixin hits that enum member. to avoid things going out of control compiler is not trying to guess what you want but stops with error, giving you a chance to fix the code.
Dec 05 2014
parent reply ketmar via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On Fri, 05 Dec 2014 09:19:27 +0000
Andre via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:

 I think I mimized the coding too much.
 What I actually want to achieve is to generate read methods
 in the structure for different data types  (Ubyte, short, int):
=20
 I thought the eponymous trick would insert the content of the
 enum instead the name itself?
=20
 string getReadMethods(string methodName, string dataType)
 {
    return dataType~` `~methodName~`(size_t idx) {
      return v_arr[idx].get!`~dataType~`; }`;
 }
=20
 template insertReadMethods(string MethodName, DataType)
 {
    enum insertReadMethods =3D getReadMethods(MethodName,=20
 DataType.stringof);
 }
=20
 struct Data
 {
 	mixin insertReadMethods!("readTinyInt", ubyte);
 	mixin insertReadMethods!("readShortInt", short);
 }
=20
 void main(){}
you musunderstood how mixin templates works. mixin templates are more like macroses than templates per se, so you don't need to assign anything to enum to get the result. i.e. string getReadMethods(string methodName, string dataType) { return dataType~` `~methodName~`(size_t idx) { return v_arr[idx].get!`~dataType~`; }`; } template insertReadMethods(string MethodName, DataType) { /*enum insertReadMethods =3D*/ // no need to do this // do that instead ;-) mixin(getReadMethods(MethodName, DataType.stringof)); } struct Data { mixin insertReadMethods!("readTinyInt", ubyte); mixin insertReadMethods!("readShortInt", short); } think about mixin templates as macro definitions which will be just inserted where you instantiated them.
Dec 05 2014
parent "Andre" <andre s-e-a-p.de> writes:
thanks a lot. That makes sense.

Kind regards
André

On Friday, 5 December 2014 at 09:29:21 UTC, ketmar via 
Digitalmars-d-learn wrote:
 On Fri, 05 Dec 2014 09:19:27 +0000
 Andre via Digitalmars-d-learn 
 <digitalmars-d-learn puremagic.com> wrote:

 I think I mimized the coding too much.
 What I actually want to achieve is to generate read methods
 in the structure for different data types  (Ubyte, short, int):
 
 I thought the eponymous trick would insert the content of the
 enum instead the name itself?
 
 string getReadMethods(string methodName, string dataType)
 {
    return dataType~` `~methodName~`(size_t idx) {
      return v_arr[idx].get!`~dataType~`; }`;
 }
 
 template insertReadMethods(string MethodName, DataType)
 {
    enum insertReadMethods = getReadMethods(MethodName, 
 DataType.stringof);
 }
 
 struct Data
 {
 	mixin insertReadMethods!("readTinyInt", ubyte);
 	mixin insertReadMethods!("readShortInt", short);
 }
 
 void main(){}
you musunderstood how mixin templates works. mixin templates are more like macroses than templates per se, so you don't need to assign anything to enum to get the result. i.e. string getReadMethods(string methodName, string dataType) { return dataType~` `~methodName~`(size_t idx) { return v_arr[idx].get!`~dataType~`; }`; } template insertReadMethods(string MethodName, DataType) { /*enum insertReadMethods =*/ // no need to do this // do that instead ;-) mixin(getReadMethods(MethodName, DataType.stringof)); } struct Data { mixin insertReadMethods!("readTinyInt", ubyte); mixin insertReadMethods!("readShortInt", short); } think about mixin templates as macro definitions which will be just inserted where you instantiated them.
Dec 05 2014