looking for some solutions? You are welcome.

SOLVED: Deducing a const l-value reference from a non-const l-value reference in C++ template

Paul Merrill:

Suppose you have the following pair of functions:

void f(const int&) { 
    // Do something, making a copy of the argument.

void f(int&&) { 
    // Do the same thing, but moving the argument.

They are fairly redundant—the only difference between the functions being whether they copy or move their argument. Of course, we can do better by re-writing this as a single template function:

template<typename T> 
void g(T&&) { 
    // Do something, possibly using std::forward to copy or move the argument.

This works, and is a commonly used idiom in practice. But the template might be instantiated into three functions, up from our two above. We can verify this occurs with the following piece of code:

#include <iostream>

template<typename T> constexpr char *type = nullptr;
template<> constexpr const char *type<int&> = "int&";
template<> constexpr const char *type<const int&> = "const int&";
template<> constexpr const char *type<int> = "int";

template<typename T> 
void g(T&&) { 
    std::cout << reinterpret_cast<void*>(&g<T>)
              << " = &g<" << type<T> << ">" << std::endl;

int main() {
    int i = 0;
    const int& cr = 0;


    return 0;


0x100f45080 = &g<int&>
0x100f45100 = &g<const int&>
0x100f45180 = &g<int>

This has added a third function for the case when T = int&, which we didn't have when we were using our non-templated function f above. In this case, we don't actually need this non-const l-value reference version of the function—given f was sufficient for our original needs—and this increases the size of our code, especially if we have many template functions written this way that call each other.

Is there a way to write our function g above so that the compiler will automatically deduce T = const int& when g(i) is called in our example code? I.e., a way where we don't have to manually write g<const int&>(i) yet still get the desired behavior.

Posted in S.E.F
via StackOverflow & StackExchange Atomic Web Robots

No comments: