Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template argument loses a lvalue reference, if not used directly

Consider this code:

#include <iostream>
#include <type_traits>
using namespace std;

template<typename T_orig> void f(T_orig& a){
    a=5;
}


template<typename T_orig, typename T=T_orig&> void g(T a){
    a=8;
}

int main() {
    int b=3;
    f<decltype(b)>(b);
    cout<<b<<endl;
    g<decltype(b)>(b);
    cout<<b<<endl;
    return 0;
}

This prints

5
5

Can somebody explain to me why in the second version the & is lost?

like image 276
Lorenzo Pistone Avatar asked Nov 29 '12 16:11

Lorenzo Pistone


1 Answers

The problem here is that type deduction takes priority over defaulted function template parameters. Therefore you get the T parameter deduced and T never deduces to a reference.

You can prevent this by making the type not deducible. A generic identity type trait can do this.

template <typename T>
struct identity { using type = T; };

template <typename T>
using NotDeducible = typename identity<T>::type;

template<typename T_orig, typename T=typename target<T_orig>::T>
void g(NotDeducible<T> a) { // blah

Or, in this particular case, you can simply get rid of the template parameter altogether.

template<typename T_orig> void g(typename target<T_orig>::T a)
like image 117
R. Martinho Fernandes Avatar answered Sep 23 '22 22:09

R. Martinho Fernandes