Class template argument deduction from constructor call

Steven Schveighoffer schveiguy at yahoo.com
Wed Oct 27 19:10:24 PDT 2010


On Wed, 27 Oct 2010 16:26:21 -0400, div0 <div0 at sourceforge.net> wrote:

> On 27/10/2010 21:02, "Jérôme M. Berger" wrote:
>> div0 wrote:
>>> On 27/10/2010 20:36, sergk wrote:
>>>> class Foo(T) {
>>>>       this(T t) {
>>>>           bar = t;
>>>>       }
>>>>       T bar;
>>>> }
>>>>
>>>> void main() {
>>>>       auto a = new Foo(123); // doesn't work
>>>>       auto b = new Foo!(int)(123); // work, but redundant
>>>> }
>>>>
>>>> Is there any technical limitations preventing this, or its just a
>>>> compiler bug?
>>>
>>> It's not a bug.
>>>
>>> I guess it could be a short cut, but it can only ever work when the
>>> class has exactly one constructor, which seems a bit of a pointless
>>> short cut and adds an unneccassiry corner case to the language spec.
>>>
>> 	Why would it only be able to work when there is exactly one
>> constructor? Doesn't function overloading work with templates?
>>
>> 	This works here:
>>
>> void foo(T) (T x) {
>> }
>>
>> void foo(T, U) (T x, U y) {
>> }
>>
>> void main()
>> {
>>      foo (3);
>>      foo (3, "azerty");
>> }
>>
>> 		Jerome
>
> class Foo(T) {
>         this(T t) {
>             bar = t;
>         }
>
> 	this(string x) {
> 	}
>
> 	this(int x) {
> 	}
>
>         T bar;
> }
>
> auto	f0 = new Foo("wtf?");
> auto	f1 = new Foo(42);
>
> What's T in any of the above?

translates to:
auto f0 = new Foo!(string)("wtf?");
auto f0 = new Foo!(int)(42);

Both of which error, since T can be neither int nor string, or Foo would  
contain conflicting constructors.

Your question is akin to asking why IFTI doesn't work on something like  
this:

T foo(T)(int x);

What Jerome was referring to is something like this:

class Foo(T)
{
   this(T t) {}
   this(T t, string x);
}

which should be unambiguous and completely doable.

The thing is, when a templated class is to be instantiated without giving  
a complete set of template arguments, then it should use IFTI.  The  
decision to try IFTI is not ambiguous, but depending on how you implement  
the constructors, the overloading can be ambiguous.

To answer the OP's question, I don't think there's anything technical  
restricting the compiler from doing this.  I believe it's been proposed  
several times.  If you want to, you can work around the issue by making a  
wrapper constructor function:

Foo!T makeFoo(T)(T t)
{
   return new Foo!T(t);
}

-Steve


More information about the Digitalmars-d-learn mailing list