Thread overview
Partial ordering of constructors with type parameters
Apr 23, 2014
Charles McAnany
Apr 23, 2014
bearophile
Apr 23, 2014
monarch_dodra
Apr 23, 2014
John Colvin
Apr 24, 2014
monarch_dodra
Apr 24, 2014
Andrej Mitrovic
Apr 24, 2014
monarch_dodra
April 23, 2014
Friends,

I have a class that needs two constructors:

class Foo{
    this(int x){}
    this(T)(T x) if(!is(T == int)){}
}
void main(){}

But this does not compile because the two constructors conflict:

buggy.d(3): Error: template buggy.Foo.__ctor(T)(T x) if (!is(T == int)) conflicts with constructor buggy.Foo.this at buggy.d(2)

Of course, I can just have one constructor that doesn't have the constraint and then use a static if to redirect to a private method, but that seems clunky to me. (not to mention it would complicate the documentation.)

Any ideas?

Cheers,
Charles McAnany.


April 23, 2014
Charles McAnany:

>     this(int x){}
>     this(T)(T x) if(!is(T == int)){}
> }
> void main(){}
>
> But this does not compile because the two constructors conflict:

Try adding the negative constraint:

this(T)(in T x) pure nothrow if(is(T == int)) {}
this(T)(in T x) pure nothrow if(!is(T == int)) {}

Bye,
bearophile
April 23, 2014
On Wednesday, 23 April 2014 at 16:44:37 UTC, Charles McAnany wrote:
> Friends,
>
> I have a class that needs two constructors:
>
> class Foo{
>     this(int x){}
>     this(T)(T x) if(!is(T == int)){}
> }
> void main(){}
>
> But this does not compile because the two constructors conflict:
>
> buggy.d(3): Error: template buggy.Foo.__ctor(T)(T x) if (!is(T == int)) conflicts with constructor buggy.Foo.this at buggy.d(2)
>
> Of course, I can just have one constructor that doesn't have the constraint and then use a static if to redirect to a private method, but that seems clunky to me. (not to mention it would complicate the documentation.)
>
> Any ideas?
>
> Cheers,
> Charles McAnany.

Update your compiler. What version are you on? This was resolved in the 2.064 release. You don't even need the "if(!is(T == int))", since non-template takes precendence.

//----
class Foo{
    this(int x){}
    this(T)(T x) {}
}
void main()
{
    auto a = new Foo(5);
}
//----

If you can't update your compiler, an alternative is to make your non-template version an actual template:

class Foo{
    this(T : int)(T x){}
    this(T)(T x) {}
}
April 23, 2014
On Wednesday, 23 April 2014 at 18:04:05 UTC, monarch_dodra wrote:
> If you can't update your compiler, an alternative is to make your non-template version an actual template:
>
> class Foo{
>     this(T : int)(T x){}
>     this(T)(T x) {}
> }

I haven't tested, but wouldn't this be more precisely equivalent?:

class Foo{
    this()(int x){}
    this(T)(T x) {}
}
April 24, 2014
On Wednesday, 23 April 2014 at 22:07:32 UTC, John Colvin wrote:
> On Wednesday, 23 April 2014 at 18:04:05 UTC, monarch_dodra wrote:
>> If you can't update your compiler, an alternative is to make your non-template version an actual template:
>>
>> class Foo{
>>    this(T : int)(T x){}
>>    this(T)(T x) {}
>> }
>
> I haven't tested, but wouldn't this be more precisely equivalent?:
>
> class Foo{
>     this()(int x){}
>     this(T)(T x) {}
> }

*That* creates a conflict though :/
April 24, 2014
On 4/24/14, monarch_dodra via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:
> *That* creates a conflict though :/

Are you sure? I can't reproduce.
April 24, 2014
On Thursday, 24 April 2014 at 10:12:15 UTC, Andrej Mitrovic via Digitalmars-d-learn wrote:
> On 4/24/14, monarch_dodra via Digitalmars-d-learn
> <digitalmars-d-learn@puremagic.com> wrote:
>> *That* creates a conflict though :/
>
> Are you sure? I can't reproduce.

Weird. I can't either. I probably accidentally tested it on 2.063? Who cares; yes, it's more practical.