www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Support implicit conversion between types

reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
I have some code like this:

struct Foo
{
	this(int i)
	{
		//do something useful
	}
}

void bar(Foo f)
{
	//do something else
}

void main()
{
	Foo f = 5;//works
	
	bar(f);//works
	
	bar(Foo(5));//works
	
	bar(5);//Error: function app.bar (Foo f) is not callable using 
argument types (int)
}


D can't implicitly convert type "int" to type "Foo", but 
constructor "Foo(int)" exists. Explicit conversion works fine.
What should I do to support this convertion implicitly?
Sep 04 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 4 September 2013 at 19:36:08 UTC, ilya-stromberg 
wrote:
 I have some code like this:

 struct Foo
 {
 	this(int i)
 	{
 		//do something useful
 	}
 }

 void bar(Foo f)
 {
 	//do something else
 }

 void main()
 {
 	Foo f = 5;//works
 	
 	bar(f);//works
 	
 	bar(Foo(5));//works
 	
 	bar(5);//Error: function app.bar (Foo f) is not callable using 
 argument types (int)
 }


 D can't implicitly convert type "int" to type "Foo", but 
 constructor "Foo(int)" exists. Explicit conversion works fine.
 What should I do to support this convertion implicitly?
What's about: void bar(int i) { bar(Foo(i)); } ?
Sep 04 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 4 September 2013 at 19:44:17 UTC, Namespace wrote:
 What's about:

 void bar(int i) {
     bar(Foo(i));
 }

 ?
No, I wrote very simple example. I have 10 "from" types and a lot of different "bar" functions. Your way will be more painful then explicit conversion.
Sep 04 2013
parent reply "Kozzi" <kozzi11 gmail.com> writes:
So you can use templates, something like this:


bool isConvertableToFoo(T)
{
     T i = void;
     return is(typeof(Foo(i)) == Foo);
}

void bar(T)(T i) if (is(T : Foo))
{
     //some code
}

void bar(T)(T i) if (!is(T : Foo) && isConvertableToFoo!T)
{
     bar(Foo(i));
}


I do not test it so it is maybe not completly correct :).
On Wednesday, 4 September 2013 at 19:54:44 UTC, ilya-stromberg 
wrote:
 On Wednesday, 4 September 2013 at 19:44:17 UTC, Namespace wrote:
 What's about:

 void bar(int i) {
    bar(Foo(i));
 }

 ?
No, I wrote very simple example. I have 10 "from" types and a lot of different "bar" functions. Your way will be more painful then explicit conversion.
Sep 04 2013
parent reply "ilya-stromberg" <ilya-stromberg-2009 yandex.ru> writes:
On Wednesday, 4 September 2013 at 20:14:06 UTC, Kozzi wrote:
 So you can use templates, something like this:
I know, it will work. But I really have **a lot of** different "bar" functions, so that way will be painful. So, the question is: what should I add to "Foo" struct to allow implicit conversions from "int" to "Foo"?
Sep 04 2013
parent reply "Adam D. Ruppe" <destructionator gmail.com> writes:
On Wednesday, 4 September 2013 at 20:25:28 UTC, ilya-stromberg 
wrote:
 So, the question is: what should I add to "Foo" struct to allow 
 implicit conversions from "int" to "Foo"?
D does not support implicit struct construction. Interestingly though, it *does* support it for functions taking classes: class Foo { this(int i) {} } void foo(Foo f...) {} void main() { foo(10); } But there's nothing like it for structs.
Sep 04 2013
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions taking classes:

 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy... Ali
Sep 04 2013
next sibling parent "Kapps" <opantm2+spam gmail.com> writes:
On Wednesday, 4 September 2013 at 21:14:26 UTC, Ali Çehreli wrote:
 On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions
taking classes:
 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy... Ali
http://dlang.org/function.html Under Typesafe Variadic Functions -> For class objects.
Sep 04 2013
prev sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
 On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
 
 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions taking
 classes:

 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy...
[...] Whoa. I never knew about this! It's ... I don't know what to say. It seems to be a cool feature, but it's also ... so scary. Implicit new's just leaves a lump in my throat. Is this an actual, intentional feature??! T -- If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
Sep 04 2013
parent reply "Kapps" <opantm2+spam gmail.com> writes:
On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
 On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
 On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:
 
 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions 
 taking
 classes:

 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy...
[...] Whoa. I never knew about this! It's ... I don't know what to say. It seems to be a cool feature, but it's also ... so scary. Implicit new's just leaves a lump in my throat. Is this an actual, intentional feature??! T
It, in theory, doesn't allocate memory: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned"
Sep 04 2013
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Sep 05, 2013 at 01:04:30AM +0200, Kapps wrote:
 On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions taking
 classes:

 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy...
[...] Whoa. I never knew about this! It's ... I don't know what to say. It seems to be a cool feature, but it's also ... so scary. Implicit new's just leaves a lump in my throat. Is this an actual, intentional feature??! T
It, in theory, doesn't allocate memory: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned"
That's even more scary. So the object implicitly constructed in this way is put on the *stack* instead of the heap, and becomes invalid after the function returns? That's just a minefield of pitfalls waiting to happen... T -- Curiosity kills the cat. Moral: don't be the cat.
Sep 04 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Sep 04, 2013 at 04:07:28PM -0700, H. S. Teoh wrote:
 On Thu, Sep 05, 2013 at 01:04:30AM +0200, Kapps wrote:
 On Wednesday, 4 September 2013 at 23:00:07 UTC, H. S. Teoh wrote:
On Wed, Sep 04, 2013 at 02:14:26PM -0700, Ali Çehreli wrote:
On 09/04/2013 01:46 PM, Adam D. Ruppe wrote:

 D does not support implicit struct construction.
That's what I knew.
 Interestingly though, it *does* support it for functions taking
 classes:

 class Foo {
          this(int i) {}
 }

 void foo(Foo f...) {}

 void main() {
          foo(10);
 }
WHAT? :) It even new's one? But it works only for the ellipsis. I wonder why the discrepancy...
[...] Whoa. I never knew about this! It's ... I don't know what to say. It seems to be a cool feature, but it's also ... so scary. Implicit new's just leaves a lump in my throat. Is this an actual, intentional feature??! T
It, in theory, doesn't allocate memory: "An implementation may construct the object or array instance on the stack. Therefore, it is an error to refer to that instance after the variadic function has returned"
That's even more scary. So the object implicitly constructed in this way is put on the *stack* instead of the heap, and becomes invalid after the function returns? That's just a minefield of pitfalls waiting to happen...
[...] Hmm. I experimented with this "feature", and found some interesting quirks: void foo(Foo f...) {...} can only be called with the same arguments as Foo's ctor, and 'f' inside the function body refers to the *single* class instance implicitly constructed. The object is actually allocated on the heap, even though the class reference is on the stack (perfectly normal). So this syntax appears to be some kind of surrogate ctor syntax, in which foo() acts as a surrogate ctor, getting the constructed object as a parameter and possibly modifying it or returning something else in its place. I can see where this might be useful, but I'm confused by the choice of syntax. This isn't a true variadic function at all; it's a ctor wrapper? Why was this syntax chosen? I'm really puzzled now. T -- One disk to rule them all, One disk to find them. One disk to bring them all and in the darkness grind them. In the Land of Redmond where the shadows lie. -- The Silicon Valley Tarot
Sep 04 2013