J'ai une situation dans mon code où je dois implémenter une forme générique de std::get()
qui fonctionne pour tout type de type Tuple. La fonction accepte une référence universelle à un Tuple
et renvoie une référence à l'élément I
du Tuple
. Je ne sais pas comment nommer le type de la référence. Malheureusement, je ne peux pas utiliser un type de retour auto
et laisser le compilateur le découvrir.Comment propager correctement le type d'une référence universelle?
Voilà ma première tentative:
#include <type_traits>
#include <tuple>
template<class T, class U>
struct propagate_reference
{
using type = U;
};
template<class T, class U>
struct propagate_reference<T&,U>
{
using type = typename std::add_lvalue_reference<U>::type;
};
template<class T, class U>
struct propagate_reference<T&&,U>
{
using type = typename std::add_rvalue_reference<U>::type;
};
template<size_t I, class TupleReference>
struct get_result
{
using tuple_type = typename std::decay<TupleReference>::type;
using type = typename propagate_reference<
TupleReference,
typename std::tuple_element<I,tuple_type>::type
>::type;
};
template<size_t I, class Tuple>
typename get_result<I,Tuple&&>::type my_get(Tuple&& t)
{
return std::get<I>(std::forward<Tuple>(t));
}
int foo(const std::tuple<int>& t)
{
return my_get<0>(t);
}
int main()
{
return 0;
}
Clang rejette ce programme:
$ clang -std=c++11 test_get.cpp
test_get.cpp:36:10: error: binding of reference to type 'int' to a value of type 'const __tuple_element_t<0UL, tuple<int> >' (aka 'const int') drops qualifiers
return std::get<I>(std::forward<Tuple>(t));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test_get.cpp:41:10: note: in instantiation of function template specialization 'my_get<0, const std::tuple<int> &>' requested here
return my_get<0>(t);
^
1 error generated.
Je soupçonne que le problème est avec la façon dont j'instancier get_result
. Qu'est-ce que je fais mal?
Pourquoi vous ne parvenez pas à retourner auto? – 101010
C'est ici que vous avez besoin de 'remove_reference' et non de' decay'. –
Qu'est-ce qui ne fonctionne pas exactement avec 'std :: get'? – PiotrNycz