, const std::tuple, B. .
f, , const std::tuple, Args... const std::tuple. B. , const-, .
, g() .
Edit:
, . std::tuple<Args...>&& , Args..., std::tuple<Args...>&& ; rvalue. , T&&, T.
, :
template <typename T>
struct is_tuple : std::false_type {};
template <typename... Args>
struct is_tuple <std::tuple<Args...>> : std::true_type {};
, :
template <typename T, typename = typename std::enable_if<
is_tuple<typename std::decay<T>::type>::value
>::type>
void f (const char* msg, T&& t)
{
std::cout << "B. " << msg << "\n";
std::cout << "B. is lval == " << std::is_lvalue_reference<T>() << "\n";
}
, :
template <typename T, template <typename...> class Template>
struct is_specialization_of : std::false_type {};
template <template <typename...> class Template, typename... Args>
struct is_specialization_of<Template<Args...>, Template> : std::true_type {};
template <typename T>
using is_tuple = is_specialization_of<T, std::tuple>;
is_specialization_of .
!
int main ()
{
f("First", 2, 5, 12345);
f("Second", std::make_tuple(2, 5, 12345));
boo the_boo;
f("Third", the_boo.g());
f("Fourth", std::forward<decltype(std::declval<boo>().g())>(the_boo.g()));
auto the_g = the_boo.g();
f("Fifth", the_g);
return 0;
}
:
A. First
B. Second
B. is lval == 0
B. Third
B. is lval == 0
B. Fourth
B. is lval == 0
B. Fifth
B. is lval == 1