C++11stlintermediate
std::add_lvalue_reference/add_rvalue_reference (C++11 Addition)
C++11 · Modern Revolution · Compiler flag: -std=c++11
Explanation
Adds lvalue or rvalue reference qualifiers to a type, useful for building reference-manipulating metafunctions.
Real-World Scenario
Construct the correct reference type in a forwarding utility based on template parameters.
Quick Snippet
snippet.cpp
#include <type_traits>
using LRef = std::add_lvalue_reference<int>::type; // int&
using RRef = std::add_rvalue_reference<int>::type; // int&&Full Example
add_reference.cpp
// CodeNebula - C++11 Example: add_reference
// Compile: g++ -std=c++11 -Wall -Wextra -o example add_reference.cpp
// Demonstrates std::add_lvalue_reference and std::add_rvalue_reference.
// These follow reference collapsing rules: T& + & = T&, T& + && = T&.
#include <iostream>
#include <type_traits>
int main() {
std::cout << "=== std::add_lvalue_reference / add_rvalue_reference ===" << std::endl;
// add_lvalue_reference adds &
using LRef = std::add_lvalue_reference<int>::type;
using LRefFromRef = std::add_lvalue_reference<int&>::type;
using LRefFromRRef = std::add_lvalue_reference<int&&>::type;
static_assert(std::is_same<LRef, int&>::value, "int -> int&");
static_assert(std::is_same<LRefFromRef, int&>::value, "int& -> int&");
static_assert(std::is_same<LRefFromRRef, int&>::value, "int&& -> int& (collapse)");
std::cout << "add_lvalue_reference<int> is int&: "
<< std::is_same<LRef, int&>::value << std::endl;
std::cout << "add_lvalue_reference<int&> is int&: "
<< std::is_same<LRefFromRef, int&>::value << std::endl;
std::cout << "add_lvalue_reference<int&&> is int&: "
<< std::is_same<LRefFromRRef, int&>::value << std::endl;
// add_rvalue_reference adds &&
using RRef = std::add_rvalue_reference<int>::type;
using RRefFromLRef = std::add_rvalue_reference<int&>::type;
using RRefFromRRef = std::add_rvalue_reference<int&&>::type;
static_assert(std::is_same<RRef, int&&>::value, "int -> int&&");
static_assert(std::is_same<RRefFromLRef, int&>::value, "int& -> int& (collapse)");
static_assert(std::is_same<RRefFromRRef, int&&>::value, "int&& -> int&&");
std::cout << "\nadd_rvalue_reference<int> is int&&: "
<< std::is_same<RRef, int&&>::value << std::endl;
std::cout << "add_rvalue_reference<int&> is int&: "
<< std::is_same<RRefFromLRef, int&>::value << std::endl;
std::cout << "add_rvalue_reference<int&&> is int&&: "
<< std::is_same<RRefFromRRef, int&&>::value << std::endl;
// void is special: references to void are not formed
std::cout << "\nadd_lvalue_reference<void> is void: "
<< std::is_same<std::add_lvalue_reference<void>::type, void>::value << std::endl;
std::cout << "\nAll checks passed!" << std::endl;
return 0;
}
// Expected output:
// === std::add_lvalue_reference / add_rvalue_reference ===
// add_lvalue_reference<int> is int&: 1
// add_lvalue_reference<int&> is int&: 1
// add_lvalue_reference<int&&> is int&: 1
//
// add_rvalue_reference<int> is int&&: 1
// add_rvalue_reference<int&> is int&: 1
// add_rvalue_reference<int&&> is int&&: 1
//
// add_lvalue_reference<void> is void: 1
//
// All checks passed!
Run command
g++ -std=c++11 -Wall -Wextra -o example add_reference.cpp