Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

forcing template type to be reference by deduction

Say I have a function func:

template<typename T>
auto func(T arg){
    std::cout << std::boolalpha;
    std::cout << "T is ref: " << std::is_reference<T>::value << '\n';
}

Is there a way I can force T to be deduced as a reference type without explicitly specifying the template parameters?

Like being able to write something like:

auto main() -> int{
    auto x = 5;
    func(std::ref(x));
}

but without having to specialize for std::reference_wrapper.

static_casting does not stop the decay of int& into int for T.

Imagine that I can not change the function signature.

like image 398
RamblingMad Avatar asked Aug 11 '26 11:08

RamblingMad


1 Answers

Imagine that I can not change the function signature.

The signature

template<typename T>
auto func(T arg) { ... }

will never deduce a reference because type deduction works on the type of the expression of the arguments, and from [expr]:

If an expression initially has the type “reference to T” (8.3.2, 8.5.3), the type is adjusted to T prior to any further analysis.

That said, template deduction only happens if the template parameters are not explicitly provided. So you can explicitly specify T:

auto main() -> int{
    auto x = 5;
    func<int&>(x); // T = int&
}

Otherwise, you could add a middle step in between:

template <typename T>
auto func_helper(T&& arg) {
    return func<T>(std::forward<T>(arg));
               ↑↑↑
}

Because, in [temp.deduct.call]:

If P is a forwarding reference and the argument is an lvalue, the type “lvalue reference to A” is used in place of A for type deduction.

So if func_helper is called with an lvalue, the template parameter P will be deduced as a reference. In your example:

func_helper(x);

T will be deduced as int&, so we explicitly call the same function as we did before: func<int&>.

func_helper(5);

T would be deduced as int, and we would call func<int>, the same as would have happened if we had called func directly.

like image 195
Barry Avatar answered Aug 13 '26 03:08

Barry