Boost logo

Boost :

Subject: Re: [boost] [local] Simplifying the parenthesized syntax
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2011-02-24 14:15:29


On Mon, Feb 7, 2011 at 5:29 PM, Steven Watanabe <watanabesj_at_[hidden]> wrote:
> AMDG
>
> On 2/7/2011 1:52 PM, Lorenzo Caminiti wrote:
>>
>> Too bad I don't think I can actually do this :( (given that `void` can
>> be _any_ token so I cannot strip it out with the pp...). I might be
>> able however to pull the return type outside the macro as in
>> Alex-Steven's syntax:
>>
>>     void BOOST_LOCAL_FUNCTION(int x, double&  y, const bind a, // [14]
>>             const bind&  b, bind&  c, bind d) {
>>         ...
>>     } BOOST_LOCAL_FUNCTION_END(f)
>>     f(1, 1.23);
>>
>> And regardless of what Alex-Steven did, I could do this by expanding
>> to a dummy variable/expression and then get its type with typeof (but
>> the library will then require typeof to determine the result type even
>> when no bound parameter is used and for a type which is specified by
>> programmes as a type -- that'd be strange):
>>
>>     void *result_ptr; // Plus append __LINE__...
>>     typedef typeof(*result_ptr) result_type;
>>     ...
>>
>
> That's almost what we did.
>
> void deduce_result();
> typedef boost::function_traits<
>  typeof(&deduce_result)>::result_type result_type;
>
> is a little better.  (It can handle references.)

This code doesn't compile on GCC (but it compiles on MSVC) within
function template:

#include <boost/typeof/typeof.hpp>
#include <boost/type_traits.hpp>

template<typename T>
void g(T x) {
    T (deduce_result)();
    typedef typename boost::function_traits< // Line 8
            BOOST_TYPEOF(deduce_result)>::result_type result_type;

    struct s {
        result_type f(T& x) { return x; } // Line 12
    } ss;
    ss.f(x);
}

void f(int x) {
    int& (deduce_result)();
    typedef boost::function_traits<
            BOOST_TYPEOF(deduce_result)>::result_type result_type;

    struct s {
        result_type f(int& x) { return x; }
    } ss;
    ss.f(x);
}

int main() {
    g(1);
    f(1);
    return 0;
}

$ g++ -Wall -Werror -I../../.. r00.cpp
r00.cpp: In member function ‘typename
boost::function_traits<__typeof__
(boost::type_of::ensure_obj(deduce_result))>::result_type
g(T)::s::f(T&) [with T = int]’:
r00.cpp:14: instantiated from ‘void g(T) [with T = int]’
r00.cpp:29: instantiated from here
r00.cpp:12: error: ‘deduce_result’ was not declared in this scope

It looks like GCC expands `deduce_result` within the struct on line 12
when typename is used instead of resolving the type at the typedef on
line 8... I don't really understand what is going on... any idea?

$ g++ --version
g++ (GCC) 4.3.4 20090804 (release) 1
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Thanks a lot!

-- 
Lorenzo

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