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.