Boost logo

Boost :

Subject: Re: [boost] Can C++11 INVOKE be defined with C++98 compilers?
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2013-04-12 01:51:22


On Thu, Apr 11, 2013 at 10:41 PM, Vicente J. Botet Escriba <
vicente.botet_at_[hidden]> wrote:

> Le 12/04/13 06:07, Jeffrey Lee Hellrung, Jr. a écrit :
>
>> On Tue, Apr 9, 2013 at 11:02 PM, Vicente J. Botet Escriba <
>> vicente.botet_at_[hidden]> wrote:
>>
>> Hi,
>>>
>>> I would like to implement C++11 INVOKE on C++98 compilers.
>>>
>>> I have a C++11 implementation on boost/thread/detail/invoke.hpp based on
>>> the one of libc++.
>>>
>>> Could this be done or there is something that can not be done inherently?
>>>
>>> Can you briefly describe what INVOKE does (or...should do)?
>>
>>
>> Hi,
>
> from the standard http://www.open-std.org/JTC1/**
> SC22/WG21/docs/papers/2012/**n3485.pdf<http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3485.pdf>
>
> 20.8.2 Requirements [func.require]
> 1 Define INVOKE(f, t1, t2, ..., tN) as follows:
> — (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class
> T and t1 is an object of
> type T or a reference to an object of type T or a reference to an object
> of a type derived from T;
>
> — ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a
> class T and t1 is not one of
> the types described in the previous item;
>
> — t1.*f when N == 1 and f is a pointer to member data of a class T and t1
> is an object of type T or a
> reference to an object of type T or a reference to an object of a type
> derived from T;
>
> — (*t1).*f when N == 1 and f is a pointer to member data of a class T and
> t1 is not one of the types
> described in the previous item;
>
> — f(t1, t2, ..., tN) in all other cases.
> 2 Define INVOKE(f, t1, t2, ..., tN, R) as INVOKE(f, t1, t2, ..., tN)
> implicitly converted to R
>

Got it.

> The libc++ implementation is
>
> // __invoke
>
> // bullets 1 and 2
>
> template <class _Fp, class _A0, class ..._Args>
> inline _LIBCPP_INLINE_VISIBILITY
> auto
> __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
> -> decltype((_VSTD::forward<_A0>(**__a0).*__f)(_VSTD::forward<_**
> Args>(__args)...))
> {
> return (_VSTD::forward<_A0>(__a0).*__**f)(_VSTD::forward<_Args>(__**
> args)...);
> }
>
[...]

I glanced at your implementation in thread/detail, and noticed you had
replaced the &&'s with BOOST_THREAD_RV_REF's, which I don't think is right
in C++03...

In C++03, you might be able to get away with defining an INVOKE (variadic)
macro that does what you want...? Hmmm...thinking about it a bit, the
difference between the pointer-to-member-function case and function
object/pointer case makes that tricky.

Maybe the best you can do in C++03 is imperfect forwarding with multiple
overloads for each arity + invokable-type combination :(

- Jeff


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