how do you write proxies for rvalues?
As an exercise to familiarize myself with rvalues I decided to write a
proxy class for plus operator. It turned out to be more difficult than
I thought.
Here is what I got (tell me if I did it wrong):
template<class T1, class T2>
class PlusProxy
{
T1 t1;
T2 t2;
public:
PlusProxy(T1&& t1, T2&& t2)
: t1(std::forward<T1>(t1)),
t2(std::forward<T1>(t2))
{}
PlusProxy(PlusProxy&& other)
: t1(std::forward<T1>(other.t1)),
t2(std::forward<T1>(other.t2))
{}
PlusProxy&& operator = (PlusProxy&& other)
{
swap(std::forward<T1>(*this), other);
}
friend
void swap(PlusProxy<T1,T2>&& p1, PlusProxy<T1,T2>&& p2)
{
swap(std::forward<T1>(p1.t1), std::forward<T1>(p2.t1));
swap(std::forward<T1>(p1.t2), std::forward<T1>(p2.t2));
}
decltype(typename std::remove_reference<T1>::type() +
typename std::remove_reference<T2>::type())
operator ()() const { return t1 + t2; }
//decltype(typename std::remove_reference<T1>::type()[0] +
// typename std::remove_reference<T2>::type()[0])
//operator [](std::size_t i) const { return t1[i] + t2[i]; }
};
template<class T1, class T2>
PlusProxy<T1, T2> MakePlus (T1&& t1, T2&& t2)
{
return PlusProxy<T1,T2>(std::forward<T1>(t1),
std::forward<T2>(t2));
}
int main()
{
int a = 1, b = 2;
std::cout << "int 1: " << MakePlus(a, b)() << std::endl;
std::cout << "int 2: " << MakePlus(a, 1)() << std::endl;
std::cout << "int 3: " << MakePlus(5, 2)() << std::endl;
std::string s1("-string1-");
std::string s2("-string2-");
std::cout << "str 1: " << MakePlus(s1, s2)() << std::endl;
std::cout << "str 2: "
<< MakePlus(s1, std::string("hello"))() << std::endl;
//std::cout << "str 3: "
// << MakePlus(s1, "world")() << std::endl;
//std::cout << "str 4: "
// << MakePlus("hello", "world")() << std::endl;
}
I compiled this example with VC2010 and gcc 4.5 and got the same
results.
The first problem I encountered was with operator[] in this example.
It turns out if I try to instantiate PlusProxy on int type, compiler
would complain about decltype(...) for operator[]. Why? There is no
instantiation of operator[], why doesn't compiler defer this check to
the point of instantiation as it would be the case if I used return
type without decltype.
The second problem was with instantiation on string types. The
expression MakePlus(s1, "world") wouldn't compile because
remove_reference did something to the string literal in decltype
expression, so I'm getting this error:
conversion from 'int' to non-scalar type 'const char [6]' requested.
Is there anything I can do to handle both string and non-string
literals in the same way?
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]