September 11, 2012
11.09.2012 22:48, Ali Çehreli пишет:
>          return to!(ReturnType!(typeof(&foo)))(42);

typeof(return)
See http://dlang.org/declaration.html#typeof

Anyway don't use it as a type of the first return. You will get:
---
Error: cannot use typeof(return) inside function foo with inferred return type
---


-- 
Денис В. Шеломовский
Denis V. Shelomovskij
September 11, 2012
On Tuesday, September 11, 2012 23:31:43 Namespace wrote:
> Sure that is the first i will do tomorrow.
> But so far no suggestions?

Use a cast. auto _cannot_ be different types depending on what you return. It must always resolve to the same type. So, in this case, either it needs to resolve to double (in which case the compiler should case) or fail to compile.

If you really want the type of the return type to be different depending on what you return, you need to use Variant (in which case it _still_ won't really be different, it'll just always be Variant, but Variant will hold a different value in its internal union, and you'll be able to get that value out as its original type later, because the Variant knows what it was). But D is statically typed, so all types must be known at compile time, and you can't have types changing based on the path of execution.

- Jonathan M Davis
September 11, 2012
Namespace:

> But so far no suggestions?

This seems to work, but solutions that use cast() are sometimes fragile (and dangerous):


auto foo(bool b) {
    final switch (b) {
        case false:
            return 20.0;
        case true:
            return cast(typeof(return))10;
    }
}
void main() {
    import std.stdio: writeln;
    writeln(foo(false));
    writeln(foo(true));
}


Bye,
bearophile
September 11, 2012
On Tuesday, September 11, 2012 23:55:40 bearophile wrote:
> Namespace:
> > But so far no suggestions?
> 
> This seems to work, but solutions that use cast() are sometimes
> fragile (and dangerous):
> 
> 
> auto foo(bool b) {
>      final switch (b) {
>          case false:
>              return 20.0;
>          case true:
>              return cast(typeof(return))10;
>      }
> }
> void main() {
>      import std.stdio: writeln;
>      writeln(foo(false));
>      writeln(foo(true));
> }

If you're going to use a cast, then use one where you give the type explicitly. Using typeof(return) is just asking for it when the compiler is clearly already having issues with the return type.

- Jonathan M Davis
September 11, 2012
On Tuesday, September 11, 2012 15:14:43 Jonathan M Davis wrote:
> If you're going to use a cast, then use one where you give the type explicitly. Using typeof(return) is just asking for it when the compiler is clearly already having issues with the return type.

And actually, in all honesty, I see no reason to use auto here. If you know what the return type is supposed to be (e.g. double), then just use double. Casting where it's unnecessary is just begging for bugs.

Based on Namespace's posts in this thread, I get the impression that what he wanted was that the return type would be either int or double depending on the value returned - i.e. he was trying to get dynamic typing - which doesn't work, because D is a static language. If that's what he wants, he needs to use Variant, and casting and the like is going to do him no good. auto was the wrong choice in the first place.

- Jonathan M Davis
September 11, 2012
You mean so?
ref Variant get() {
    return this._num; // with Variant _num;
}

alias get this;

and then:
int i = zahl.get!int?
No. Then I use my solution as you can see on DPaste. If Variant works only this way I can also set float to the return type an cast if I need to int.
And with my solution I have in calculation a numeric value and doesn't have to cast with Variant's get method.

September 11, 2012
On Wednesday, September 12, 2012 00:29:32 Namespace wrote:
> You mean so?
> ref Variant get() {
>      return this._num; // with Variant _num;
> }
> 
> alias get this;
> 
> and then:
> int i = zahl.get!int?
> No. Then I use my solution as you can see on DPaste. If Variant
> works only this way I can also set float to the return type an
> cast if I need to int.
> And with my solution I have in calculation a numeric value and
> doesn't have to cast with Variant's get method.

If want the result to always be the same type, then either use the explicit type or auto (though clearly auto is having some issues right now, so it might be best to avoid it if you're returning stuff that differs in type and needs to be converted). If you want the result to differ in type depending on the value returned, then you need Variant in order to simulate dynamic typing.

I'm not quite sure what you're trying to do with your code, but if you use Variant, you'll need to use get or coerce to get its value from it, which it doesn't sound like what you want to do. If that's the case, then your get function needs to always return the same type - be it int or float or double or whatever, and you might as well just use the explicit type rather than auto, since it's a primitive type, not a complicated, templated one (which is the main reason to use auto for the return type of a function).

- Jonathan M Davis
September 12, 2012
On Tuesday, 11 September 2012 at 21:31:17 UTC, Namespace wrote:
> On Tuesday, 11 September 2012 at 21:13:02 UTC, bearophile wrote:
>> Namespace:
>>
>>> I have this code, but it works not as expected:
>>> http://dpaste.dzfl.pl/6ce5b4dd
>>
>> I suggest to file a bug:
>>
>>
>> auto foo(bool b) {
>>    final switch (b) {
>>        case true:
>>            return 10;
>>        case false:
>>            return 20.0;
>>    }
>> }
>> void main() {
>>    import std.stdio: writeln;
>>    writeln(foo(true));
>>    writeln(foo(false));
>> }
>>
>>
>> The acceptable results are a compile-time error for type mismatch, or a conversion of both literals to double. Probably the second is better. But a silent bit-level cast is not acceptable.
>>
>> Bye,
>> bearophile
>
> Sure that is the first i will do tomorrow.
> But so far no suggestions?

Just this one. You can use an anonymous union in your Num struct, so you can write "obj.ivalue" rather than obj._num.ivalue":

struct Num {
private:

  final enum Type {
    None,
    Float,
    Int
  }

  union {
    float fvalue;
    int ivalue;
  }

  Type _type;

  ....

Graham

September 12, 2012
Done, thank you. :)
1 2 3
Next ›   Last »