Search code examples
d

Why I get no identifier for declarator ....?


Why I get no identifier for declarator .... ?

mixin are useless in this case but that is a minimal example of my problem.

tlvar is type of TL so i do not see where is the problem.

Code also on dpaste, same error with dmd or ldc.

Thanks for your help

import std.stdio;
import std.typecons;

struct Data{
    int x;
    int y;
}

template getcode(T)
{
    mixin(`
          alias TL = Tuple!(
                            int,"x",
                            int,"y"
                           );
          `);
    TL tl;
    mixin(`
          tl.x = 10;
          tl.y = 5;
          `);
}

void main()
{

    getcode!Data;
    writeln( tl.x );
}

Solution

  • Your problem is that templates can only contain declarations, not statements or expressions. This is the offending code:

    mixin(`
          tl.x = 10;
          tl.y = 5;
          `);
    

    These are assignments, not declarations. This is why you get the weird error message "Error: no identifier for declarator tl.x". The compiler thinks you are trying to make a declaration of a variable, and it can't find the type "tl.x"... or something like that. The solution is to set the value of the tuple inline, like so:

    template getcode(T)
    {
        mixin(`alias TL = Tuple!(int, "x", int, "y");`);
        TL tl = TL(10, 5);
    }
    

    Or, to better match your original code:

    template getcode(T)
    {
        mixin(`alias TL = Tuple!(int, "x", int, "y");`);
        TL tl = mixin(`TL(10, 5)`);
    }
    

    There is now another problem. In main, where you instantiate the template, you will get the error "Error: getcode!(Data) has no effect". This is because a template instantiation on its own is not a declaration. You have to either alias it to a symbol, or mix it in using a mixin statement.

    Aliasing it to a symbol will allow you to access the declarations inside the template through that symbol, and mixing it in puts the template's declarations into the scope it's instantiated in. I would recommend the first option, as it's more hygenic. You shouldn't use mixin unless you absolutely have to.

    void main()
    {
        //Error: getcode!(Data) has no effect
        //getcode!Data;
    
        //Ok
        //mixin getcode!Data;
        //writeln( tl.x );
    
        //Ok
        alias Code = getcode!Data;
        writeln( Code.tl.x );
    }
    

    You can see my corrected version of your code here:

    http://dpaste.dzfl.pl/f6152a35bfc8