Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c++
Subject: Re: forward variable number of arguments precisely to a template method
Date: Fri, 06 Sep 2019 03:17:08 -0700
Organization: A noiseless patient Spider
Lines: 49
Message-ID: <86imq5wwyj.fsf@mailhub.linuxsc.com>
References:
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="1b4e4211bfac39026673841300f74c7e"; logging-data="21487"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+bt6RPAz+44YWcOoxPpBXfW8s94MmDrgA="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:0wxBKe9jpVVLRKAmylEYZ5XuP4Y= sha1:iWs3PsxDcIULHK2UzyK4/DBy/c8=
Xref: csiph.com comp.lang.c++:68255
Pavel writes:
> Trying to write generic code for forwarding arguments via a
> template method to methods defined in an interface precisely (in
> particular, all references should be forwarded as references and
> values as values). Using gcc 4.8.5 and -std=c++11 (cannot
> change). The best code I could come up with so far is below.
>
> Taking the below code as an example, I want generated `callMethod'
> to have exactly same last 2 parameter types as the interface
> method it calls ((I,I) for ma, (const I&, const I&) for mb and
> (const I&, I) for mc). [...]
I took a pretty long look at this. I think you're up against a
hard problem. Here's the best I came up with (please excuse
some minor changes in names, etc):
template< typename T, const int >
class Caller {
T &worker;
public:
Caller( T &w ) : worker( w ) {}
template< typename ... Stuff > void
invoke( void (T::*pmf)( Stuff ... ), Stuff ... stuff ){
(worker.*pmf)( stuff ... );
}
};
and in main(), instead of
Caller(a).callMethod( &IA::ma, i1, i2 );
Caller(a).callMethod( &IA::mb, i3, i4 );
Caller(a).callMethod( &IA::mc, i5, i6 );
I have
Caller(a).invoke< I , I >( &IA::ma, i1, i2 );
Caller(a).invoke< const I &, const I & >( &IA::mb, i3, i4 );
Caller(a).invoke< const I &, I >( &IA::mc, i5, i6 );
I looked at using forward(), but I don't think it helps you. I
should add though that I'm still pretty much of a novice with
those things.
My sense is that you will be stuck with having to give the
template argument types explicitly rather than having them be
deduced. I have a similar disclaimer about not having any
level of expertise in template type deduction.