Search code examples
c++templatesc++11pass-by-referenceuniversal-reference

A trick for optional reference using universal references?


I've found a trick to use optional reference in standard C++11. Do you think that this technique is reliable and the behaviour is well defined according to the the C++ standard ?

// Optional reference using C++11 
// V. Reverdy - 2013
#include <iostream>
#include <type_traits>

template <class T = int, class = typename std::enable_if<std::is_same<typename std::decay<T>::type, int>::value>::type>
void f(T&& n = T())
{
    std::cout<<"--------"<<std::endl;
    std::cout<<"is const = "<<std::is_const<T>::value<<std::endl;
    std::cout<<"is reference = "<<std::is_reference<T>::value<<std::endl;
    std::cout<<"is lvalue reference = "<<std::is_lvalue_reference<T>::value<<std::endl;
    std::cout<<"is rvalue reference = "<<std::is_rvalue_reference<T>::value<<std::endl;
    std::cout<<"--------"<<std::endl;
    n *= 2;
} 

int main(int argc, char* argv[])
{
    int n = 42;
    std::cout<<"n = "<<n<<std::endl;
    f();
    std::cout<<"n = "<<n<<std::endl;
    f(n);
    std::cout<<"n = "<<n<<std::endl;
    return 0;
}

The result is :

n = 42
--------
is const = 0
is reference = 0
is lvalue reference = 0
is rvalue reference = 0
--------
n = 42
--------
is const = 0
is reference = 1
is lvalue reference = 1
is rvalue reference = 0
--------
n = 84

It seems to work on all compilers available on liveworkspace : LWS


Solution

  • Wat.

    Firstly, what you have "achieved" could be far simpler achieved by, say, overloading. And secondly, it is not the same as an optional reference at all. The optional reference is a value, which may or may not contain a reference at run-time. The behaviour is well-defined but it's neither desirable nor an optional reference. Binding references to temporaries as default arguments is nice in some situations but it's a billion miles from an optional reference.