Можно ли сделать void foo
взять универсальную ссылку вместо rvalue в случае параметра шаблона шаблона, как в следующем коде?
#include <iostream>
#include <string>
using namespace std;
template <int I>
struct s
{
string str;
};
template <template<int> class T, int U>
void foo(T<U>&& param)
{
cout << param.str << endl;
}
int main()
{
s<5> thing;
foo( thing );
}
Я получаю следующая ошибка:
error: cannot bind 's<5>' lvalue to 's<5>&&'
Нет, универсальные ссылки опираются на аргумент шаблона, выводимый как ссылка lvalue. T
не может быть ссылкой на lvalue в T<U>&&
, так что это не работает.
Что может работать, используя T&&
и используя SFINAE, чтобы он соответствовал некоторым T<U>
,
template <template<int> class T, int U>
void foo_helper(const volatile T<U>&);
template <template<int> class T, int U>
void foo_helper(const volatile T<U>&&);
template <typename T, typename = decltype(foo_helper(std::declval<T>()))>
void foo(T&& param)
{
cout << param.str << endl;
}
При необходимости вы также можете предоставить черты типа помощника, если foo
предназначен для использования вашего T
или же U
непосредственно.