On Mon, 30 Sep 2013 19:54:56 -0700, Gavin Lambert
On 10/1/2013 2:46 PM, Quoth Mostafa:
struct SomeUserClass { static void foo(int const x) { SomeCodeGenClass::foo(x); } };
SomeCodeGenClass::foo is a mere parameter forwarder, so the goal is to do it as efficiently as possible. It's signature is constructed from SomeUserClass::foo. For correctness, that should be:
void SomeCodeGenClass::foo(int const & x)
This would also be the correct signature for foo(int x) -- because they're the same thing.
But, function_typesSomeUserClass::foo::arg1_type resolves to int, so that add_reference'ing will give the following signature for the TMP constructed SomeCodeGenClass::foo
void SomeCodeGenClass::foo(int & x)
A simple add_reference is obviously the wrong thing to be doing then.
In general, you can take any parameter type T and wrap it as a "const T&" (or if you prefer, "T const&") and it will do the right thing, unless T was already a reference. But note that you must use a const reference -- a non-const reference won't work.
Not in my particular use case. The code I was working is generated by a mix of PPMP and TMP techniques. The argument x is eventually forwarded to some user block of code, where the user expects it to be of the same type as the one he/she specified in the signature of SomeUserClass::foo. So had the user specified this instead: struct SomeUserClass { static void foo(int x) { SomeCodeGenClass::foo(x); } }; Then it is expected that x would be mutable in that forwarded-to block of code. (The fact that it's actually a reference when it arrives there is immaterial to the user.) Now, I can make a copy of x before the final stage, but that would partially defeat the purpose of passing by reference, since a copy is already made at SomeUserClass::foo. In sum, this particular problem maybe restricted to PPMP/TMP code, and it maybe that pure TMP code doesn't suffer from this.