Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2008-04-09 15:30:49


On Apr 9, 2008, at 1:11 PM, Andrei Alexandrescu wrote:
> Howard Hinnant wrote:
>> On Apr 8, 2008, at 9:40 PM, Steven Watanabe wrote:
>>> AMDG
>>>
>>> Howard Hinnant wrote:
>>>>> template <class T, class U>
>>>>> decltype(true ? T() : U()) Min(T&& a, U&& b) {
>>>>> return b < a ? b : a;
>>>>> }
>>>>>
>>> Should this really work if T of U is a reference type and thus
>>> cannot
>>> be default constructed?
>>
>> You're right. Not by current language rules. The reported error
>> message could have been better.
>
> I knew this is going to come. That's why I'd tried this with conceptg
> ++:
>
> typedef const int& cintr;
> typedef int& cint;
>
> int main()
> {
> int a;
> int x = cintr();
> int y = cint();
> }
>
> Turns out this program compiles fine. I assumed the compiler was
> right,
> and I was also self-pressured to make Min's definition self-contained,
> so I just went with that trick.

Interesting, thanks.

>
>
>> By coincidence I'm dealing with a similar problem here: http://home.twcny.rr.com/hinnant/cpp_extensions/time2_demo.html
>> , and dealing with it via a promote trait, quite similar to what
>> I've seen in boost. I.e. the Min signature might look like:
>>
>> template <class T, class U> typename promote<T, U>::type Min(T&&
>> a, U&& b);
>>
>> With the *default* (and preferably standardized) promote trait
>> looking
>> like:
>>
>> template <class T, class U>
>> struct promote
>> {
>> private:
>> static T t;
>> static U u;
>> public:
>> typedef decltype(true ? static_cast<T&&>(t) :
>> static_cast<U&&>(u)) type;
>> };
>>
>> // promote is specializable for client-defined types
>
> So it does look like there is a simple solution to min and max! Any
> interest in submitting a revised 2199?
>
> Oh, and in order to save space and default-constructor-related
> aggravation, you may want to use static functions in lieu of static
> variables. In the process, I also changed name to what I think is a
> better one:
>
> template <class T, class U>
> struct common_type
> {
> private:
> static T t();
> static U u();
> public:
> typedef decltype(true ? static_cast<T&&>(t()) :
> static_cast<U&&>(u())) type;
> };
>
> Actually, heck, just have the functions return the rvalue ref
> directly:
>
> template <class T, class U>
> struct common_type
> {
> private:
> static T&& t();
> static U&& u();
> public:
> typedef decltype(true ? t() : u()) type;
> };
>
> Then you define Min like this:
>
> template <class T, class U>
> typename common_type<T, U>::type
> Min(T&& a, U&& b) {
> return b < a ? b : a;
> }
>
> and you're home free. At least my few tests pass fine.
>
> I think you're dead on that common_type/promote belongs to the
> standard.
> I'd defined a template called CommonType in the D standard library:
>
> http://www.digitalmars.com/d/2.0/phobos/std_traits.html#CommonType
>
> and it turned out to be mightily useful. (Notice that it takes a
> variable number of types.)

That's a nice improvement, thanks.

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk