Jump to page: 1 2
Thread overview
MIN MAX problem
Mar 13, 2007
freeagle
Mar 13, 2007
torhu
Mar 13, 2007
freeagle
Mar 13, 2007
BCS
Mar 13, 2007
Walter Bright
Mar 13, 2007
freeagle
Mar 14, 2007
Daniel Keep
Mar 14, 2007
Hasan Aljudy
Mar 14, 2007
janderson
Mar 14, 2007
freeagle
Mar 14, 2007
Walter Bright
Mar 14, 2007
janderson
March 13, 2007
Hey all,

from what I know, there is (currently?) no way of implementing min/max template functions that could dynamically change return type depending on the result of comparison. I think that this problem can be "solved" easily. When used in C++, there is no problem with the return type as min/max are coded as macros. But there is always probability that the result of the min/max will be cast into appropriate type, because variables cant be both float and int at the same time, for example.
That means, when you write in C++

float f = 1.0f, result;
int a = 2;
result = MAX(f, a);

the result is cast to float when assignment to the variable is being done. This means you always know of what type you want the result to be.
I say we could move the casting into the function itself, like this:

T max(T, U)(T arg1, U arg2)
{
	return cast(T) (arg1 > arg2 ? arg1 : arg2);
}

and make it a standard that the type of the first argument will always be the returning type of the min/max function.

Just a thought

freeagle
March 13, 2007
freeagle wrote:
> the result is cast to float when assignment to the variable is being done. This means you always know of what type you want the result to be.
> I say we could move the casting into the function itself, like this:
> 
> T max(T, U)(T arg1, U arg2)
> {
> 	return cast(T) (arg1 > arg2 ? arg1 : arg2);
> }
> 
> and make it a standard that the type of the first argument will always be the returning type of the min/max function.

You can use typeof to get the common type, like this:

typeof(T + U) max(T, U)(T arg1, U arg2)
{
        return arg1 > arg2 ? arg1 : arg2;
}
March 13, 2007
torhu wrote:
> freeagle wrote:
>> the result is cast to float when assignment to the variable is being done. This means you always know of what type you want the result to be.
>> I say we could move the casting into the function itself, like this:
>>
>> T max(T, U)(T arg1, U arg2)
>> {
>>     return cast(T) (arg1 > arg2 ? arg1 : arg2);
>> }
>>
>> and make it a standard that the type of the first argument will always be the returning type of the min/max function.
> 
> You can use typeof to get the common type, like this:
> 
> typeof(T + U) max(T, U)(T arg1, U arg2)
> {
>         return arg1 > arg2 ? arg1 : arg2;
> }

havent seen in the docs something like type adding ?! anyway, my guess is that the typeof(T + U) expresion always return the the same type for each couple of types. so float + int would always return float? what if you want it to return int?
March 13, 2007
torhu wrote:
> You can use typeof to get the common type, like this:
> 
> typeof(T + U) max(T, U)(T arg1, U arg2)
> {
>         return arg1 > arg2 ? arg1 : arg2;
> }

The + isn't always defined, so you can use:

typeof(true ? cast(T)0 : cast(U)0) max(T, U)(T x1, U x2)
{
    return x1 > x2 ? x1 : x2;
}
March 13, 2007
Reply to freeagle,

> torhu wrote:
> 
>> freeagle wrote:
>> 
>>> the result is cast to float when assignment to the variable is being
>>> done. This means you always know of what type you want the result to
>>> be. I say we could move the casting into the function itself, like
>>> this:
>>> 
>>> T max(T, U)(T arg1, U arg2)
>>> {
>>> return cast(T) (arg1 > arg2 ? arg1 : arg2);
>>> }
>>> and make it a standard that the type of the first argument will
>>> always be the returning type of the min/max function.
>>> 
>> You can use typeof to get the common type, like this:
>> 
>> typeof(T + U) max(T, U)(T arg1, U arg2)
>> {
>> return arg1 > arg2 ? arg1 : arg2;
>> }
> havent seen in the docs something like type adding ?! anyway, my guess
> is that the typeof(T + U) expresion always return the the same type
> for each couple of types. so float + int would always return float?
> what if you want it to return int?
> 

The type of every function is fixed at compile time, It can't return a float sometimes and an int others.


March 13, 2007
Walter Bright wrote:
> torhu wrote:
>> You can use typeof to get the common type, like this:
>>
>> typeof(T + U) max(T, U)(T arg1, U arg2)
>> {
>>         return arg1 > arg2 ? arg1 : arg2;
>> }
> 
> The + isn't always defined, so you can use:
> 
> typeof(true ? cast(T)0 : cast(U)0) max(T, U)(T x1, U x2)
> {
>     return x1 > x2 ? x1 : x2;
> }
 could you please explain what this means? coz i'd say it always returns T

typeof(true ? cast(T)0 : cast(U)0)

And, i think this wont work for classes that overload the >,< etc operator, as you can't do cast(class)0, can you?
March 14, 2007
freeagle wrote:
> Walter Bright wrote:
>> torhu wrote:
>>> You can use typeof to get the common type, like this:
>>>
>>> typeof(T + U) max(T, U)(T arg1, U arg2)
>>> {
>>>         return arg1 > arg2 ? arg1 : arg2;
>>> }
>>
>> The + isn't always defined, so you can use:
>>
>> typeof(true ? cast(T)0 : cast(U)0) max(T, U)(T x1, U x2)
>> {
>>     return x1 > x2 ? x1 : x2;
>> }
>  could you please explain what this means? coz i'd say it always returns T
> 
> typeof(true ? cast(T)0 : cast(U)0)
> 
> And, i think this wont work for classes that overload the >,< etc operator, as you can't do cast(class)0, can you?

In the archives somewhere, there is a long thread discussing an implementation of min (or max; can't remember).  From what I do remember, it basically boiled down to "good grief this is actually really hard once you involve types!".

Might be worth searching for it and having a read.  In fact, because I'm feeling so helpful this morning:

http://www.digitalmars.com/d/archives/digitalmars/D/challenge_implement_the_max_function_47026.html

Hope this helps

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
March 14, 2007

Daniel Keep wrote:
> 
> In the archives somewhere, there is a long thread discussing an
> implementation of min (or max; can't remember).  From what I do
> remember, it basically boiled down to "good grief this is actually
> really hard once you involve types!".

Doesn't the new mixin construct solve the issue?

March 14, 2007
Walter Bright wrote:
> torhu wrote:
>> You can use typeof to get the common type, like this:
>>
>> typeof(T + U) max(T, U)(T arg1, U arg2)
>> {
>>         return arg1 > arg2 ? arg1 : arg2;
>> }
> 
> The + isn't always defined, so you can use:
> 
> typeof(true ? cast(T)0 : cast(U)0) max(T, U)(T x1, U x2)
> {
>     return x1 > x2 ? x1 : x2;
> }

Is there a plan to allow:

typeof(true ? x1 : x2) max(T, U)(T x1, U x2)
{
    return x1 > x2 ? x1 : x2;
}


Andrei
March 14, 2007
freeagle wrote:
> Hey all,
> 
> from what I know, there is (currently?) no way of implementing min/max template functions that could dynamically change return type depending on the result of comparison. I think that this problem can be "solved" easily. When used in C++, there is no problem with the return type as min/max are coded as macros. But there is always probability that the result of the min/max will be cast into appropriate type, because variables cant be both float and int at the same time, for example.
> That means, when you write in C++
> 
> float f = 1.0f, result;
> int a = 2;
> result = MAX(f, a);
> 
> the result is cast to float when assignment to the variable is being done. This means you always know of what type you want the result to be.
> I say we could move the casting into the function itself, like this:
> 
> T max(T, U)(T arg1, U arg2)
> {
>     return cast(T) (arg1 > arg2 ? arg1 : arg2);
> }
> 
> and make it a standard that the type of the first argument will always be the returning type of the min/max function.
> 
> Just a thought
> 
> freeagle

In C++ you can use some copy constructor / assignment magic with a proxy object to get the task done.  That technique won't handle different types in the same query though.

-Joel
« First   ‹ Prev
1 2