2015-02-19 4 views
0

Возможно ли сделать void foo универсальной ссылкой вместо ссылки rvalue в случае шаблона шаблона, например, в следующем коде?unversal reference in void foo (T <U> && param)

#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); 
} 

Я получаю following error:

error: cannot bind 's<5>' lvalue to 's<5>&&' 
+1

№ Ссылка для пересылки (официальное название так называемой «универсальной ссылки») должна быть «T &&», где «T» - это параметр типа шаблона, который выводится. –

ответ

1

Нет, универсальные ссылки полагаются на аргумент шаблона быть выведены в качестве ссылки 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 непосредственно.

+0

В этом примере показано, как использовать U в foo: http://coliru.stacked-crooked.com/a/0cc2f28bf549bfbf – MofX

+0

@MofX Поскольку у меня уже есть 'foo_helper', я думаю, что было бы проще использовать' typename Traits = decltype (foo_helper (std :: declval )) 'и make' foo_helper' return 'foo_traits ' (который будет содержать любые 'foo' потребности). – hvd