Error using templates: "cannot use template to add field to aggregate '<class>'"
Chris Wright via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Jan 25 08:12:58 PST 2016
On Mon, 25 Jan 2016 14:51:21 +0000, pineapple wrote:
> I'm getting several of these since I'm trying to do the same thing in a
> few places. Here's a complete error:
>
> path\to\file.d(55): Error: variable
> units.unitvalue.opmethod!("sum(in unitvalue value)",
> "add(value)").methodtemplate cannot use template to add field to
> aggregate 'unitvalue'
> path\to\file.d(127): Error: template instance
> units.unitvalue.opmethod!("sum(in unitvalue value)", "add(value)") error
> instantiating
That looks like the right error.
> template opmethod(string methoddef, string methodcall){
> const char[] methodtemplate =
Change it from 'const' to 'enum' and Bob's your uncle.
Short explanation:
'enum' refers to compile-time constants. 'const' is a promise that you
will not mutate a variable through that reference. Anything that's not a
compile-time constant in an aggregate body requires storage space within
that aggregate, resulting in an unbounded set of fields.
Exhaustive explanation:
'const' indicates that you cannot mutate the data through this reference
(but it can be mutated elsewhere). It's not referring to compile-time
constants. For instance, it's entirely legal (and reasonable) to write:
class OptParse {
const(string[]) args;
this(const(string[]) args) {
this.args = args;
}
}
void main(string[] args) {
new OptParse(args);
}
Which indicates that OptParse is not going to modify the args array.
You're grabbing command-line arguments and passing them in, which means
they're not a compile-time constant. So the OptParse class has to include
a storage slot reserved for the 'args' variable.
In your case, 'methodtemplate' isn't declared as a compile-time constant.
It has an initializer that's a compile-time constant, but you aren't
guaranteeing that the value isn't going to be changed.
That would be fine, but it's inside a template. Templates can be
instantiated a potentially unlimited number of times. So the compiler
comes across this type, tries to compute its size and fields -- but it
doesn't know for certain at this point how many times you're
instantiating the template. So it can't list out all the fields.
It would be possible if D compiled a whole program at once. This would
prevent you from publishing closed-source libraries, however, and
increase compilation times.
More information about the Digitalmars-d-learn
mailing list