Created attachment 980
Test cases for this issue.
----
struct S{ ... }
S(...) // (a)
S s;
s(...) // (b)
----
We should lookup them following order:
(a) From type
1. Constructor call
Constructors are defined with arguments (>= 1), and hide any signature of
static opCalls.
2. Static opCall
If no constructors exists, static opCalls are checked.
3. When matching with 1 and 2 failed, struct literal syntax is checked.
4. Otherwise makes error.
(b) From object
1. Matchings are tested against static opCalls and object (=non-static)
opCalls.
2. No opCalls makes error.
These rules reject following current dmd bugs:
- Constructors are visible from object.
This problem pointed out by issue 1840, issue 4053 and issue 4253.
- Object opCalls are visible from type.
Comment #1 by bearophile_hugs — 2011-05-19T04:30:50Z
*** Issue 4253 has been marked as a duplicate of this issue. ***
Comment #4 by k.hara.pg — 2011-06-21T07:03:40Z
*** Issue 4053 has been marked as a duplicate of this issue. ***
Comment #5 by wfunction — 2011-09-26T10:38:11Z
An instance-level opCall should not disable the regular constructor.
Test case:
struct Adder {
int v;
auto opCall(int x) { return x + v; }
}
auto adder(int v) {
return Adder(v); // How do I call the constructor??
}
int main() {
auto a = adder(5);
}
Comment #6 by k.hara.pg — 2012-01-23T04:59:33Z
*** Issue 2916 has been marked as a duplicate of this issue. ***
Comment #7 by bearophile_hugs — 2012-05-27T18:14:48Z
See also Issue 4678 and Issue 7210 and Issue 1840
This is a problem I hit often.
Comment #8 by k.hara.pg — 2012-05-30T19:39:35Z
*** Issue 4678 has been marked as a duplicate of this issue. ***
Comment #9 by jens.k.mueller — 2012-08-14T07:41:29Z
This bug makes using opCall practically useless.
As soon as you have a constructor you get a compile error when you want to call opCall using the bracket syntax.
E.g. the following code does not compile.
struct F {
this(int a) { }
int opCall(int x, int y)
{
return 1;
}
}
unittest
{
F f;
int i;
i = f(3,4,5);
// Error: constructor F.this (int a) is not callable using argument
// types (int,int,int)
// workaround: i = f.opCall(3,4,5);
}
This is v2.060 on Linux.
Comment #10 by github-bugzilla — 2012-10-06T06:57:56Z
Comment #11 by bearophile_hugs — 2012-10-06T11:08:35Z
(In reply to comment #5)
> struct Adder {
> int v;
> auto opCall(int x) { return x + v; }
> }
>
> auto adder(int v) {
> return Adder(v); // How do I call the constructor??
> }
>
> int main() {
> auto a = adder(5);
> }
A little reduced:
struct Adder {
int v;
int opCall(int x) { return x + v; }
}
void main() {
auto a = Adder(5);
}
It gives:
temp.d(6): Error: need 'this' for opCall type int(int x)
Is it expected that the instance opCall disables the implicitly created struct ctor?
Comment #12 by k.hara.pg — 2012-10-06T16:42:01Z
(In reply to comment #11)
> (In reply to comment #5)
>
> A little reduced:
>
> struct Adder {
> int v;
> int opCall(int x) { return x + v; }
> }
> void main() {
> auto a = Adder(5);
> }
>
>
> It gives:
>
> temp.d(6): Error: need 'this' for opCall type int(int x)
>
> Is it expected that the instance opCall disables the implicitly created struct
> ctor?
At least it is same as before merging my pull, except small error message difference.
It is still a corner case of language spec, but I think it is an expected behavior.
Because, the operator overloading mechanism just consider whether the function named opXXXX exists or not, and doesn't consider whether the opXXXX is really static or not.
Comment #13 by k.hara.pg — 2012-10-06T16:44:29Z
*** Issue 7210 has been marked as a duplicate of this issue. ***
Comment #14 by bearophile_hugs — 2012-10-07T05:51:58Z
(In reply to comment #12)
> It is still a corner case of language spec, but I think it is an expected
> behavior.
> Because, the operator overloading mechanism just consider whether the function
> named opXXXX exists or not, and doesn't consider whether the opXXXX is really
> static or not.
See a discussion thread:
http://forum.dlang.org/thread/[email protected]