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