In some class O, I have templated function test2
:
struct A{int value;};
struct O{
A value;
template<typename Args>
static void test2(Args &&args){
std::cout << std::endl << "!!!" << std::is_rvalue_reference<decltype(args)>::value << std::endl;
}
};
Than, I want to call this function from another one:
template<typename Args>
void test(Args &&args){
using t = decltype(std::forward<Args>(args).value);
std::cout << std::is_rvalue_reference<decltype(args)>::value;
std::cout << std::is_rvalue_reference<decltype(std::forward<Args>(args).value)>::value;
std::cout << std::is_rvalue_reference<t>::value;
// All ok
O.test2(std::forward<Args>(args).value);
// Alvays rvalue, even if agrs is lvalue
O::template test2<t>(
std::forward<t>(
std::forward<Args>(args).value
)
);
// Nor work at all, cant cast A to A&&
O::template test2<t>(
std::forward<Args>(args).value
);
);
}
http://coliru.stacked-crooked.com/a/3bbf040904845a54
If I just pass std::forward<Args>(args).value
without specifying template type, it deduce type correctly, but what if I have to pass type, how should I call function than?
It seems I can't manually deduce type correctly.
UPDATE
I need to specify arguments explicitly, because I have function like this (pseudo-code):
//initially call wind from somewhere.
// Tuple defined in class and is std::tuple
template<class Callback, class ...Args>
void wind(Tuple&& tuple, Callback &&callback){
using elementT = decltype(std::get<index>(std::forward<Tuple>(tuple)));
///
/// !!! Problem here !!!
///
callback.template operator()<elementT, Args...>( std::get<index>(std::forward<Tuple>(tuple)) ); // std::get automatically return &/&&
// recursivly call wind until the end
wind<Callback, Args...>( std::forward<Tuple>(tuple), std::forward<Callback>(callback));
}
// callback looks like:
struct CallMe{
// Args provide type info. No function arguments here.
template<class Data, class ...Args>
void operator(Data &&data){
}
}
This question related to call both - wind and callback() functions.
Based on knowledge that objects, inside rvalue referenced object, also rvalue referenced. I decide to ended up with this (inspired by https://stackoverflow.com/a/24083200/1559666):
template<class T, class FieldT>
using addRefU = typename std::conditional<
std::is_rvalue_reference<T>::value,
typename std::add_rvalue_reference< FieldT >::type,
typename std::conditional<
std::is_rvalue_reference<FieldT>::value,
typename std::add_rvalue_reference< FieldT >::type,
typename std::add_lvalue_reference< FieldT >::type
>::type
>::type;
T T::value(FieldT) resolve
------------------------------------------------------------
rvalue lvalue rvalue
rvalue rvalue rvalue
lvalue rvalue rvalue
lvalue lvalue lvalue
using t = addRefU<decltype(args), decltype(args.value)>;
O::template test2<t>(
static_cast<t>(args.value)
);
http://coliru.stacked-crooked.com/a/40d10f5a2f45c288
Short enough, as for me.
P.S. If someone have some precautions about this, I would gladly listen to them.