(!) Please ask about problems and questions regarding this tutorial on answers.ros.org. Don't forget to include in your question the link to this page, the versions of your OS & ROS, and also add appropriate tags.

Reference Wrappers

Description: When you want to pass a reference, but are only permitted to pass a copy.

Keywords: ecl reference wrappers

Tutorial Level: INTERMEDIATE

Introduction

There are situations where you may wish to overload a function with both non-referenced and referenced arguments. Unfortunately, this is not directly possible with c++, it usually results in an ambiguity.

   1 class A {
   2 public:
   3     template <typename T>
   4     void f(T i) { cout << "Not a reference input" << endl; }
   5 
   6     template <typename T>
   7     void f(T &i) { cout << "A reference input" << endl; }
   8 }

One way to resolve this is to create a wrapper with a pointer to the object inside it (we call this a reference wrapper) and pass it to the function as you would normally pass a copy. Once accepted, the function can use some metaprogramming logic to determine the fate of the accepted copy or reference wrapper.

Compiling & Linking

Include the following at the top of any translation unit:

   1 #include <ecl/utilities.hpp>
   2 
   3 using ecl::ReferenceWrapper
   4 using ecl::ref
   5 using ecl::cref
   6 using ecl::addressOf

If outside ros, you will also need to link to ecl_utilities.

Usage

ReferenceWrapper

The easiest way to generate a reference wrapper is via the convenience functions ref/cref. For example, below illustrates a referenced function object passed to a thread.

   1 Thread thread(ref(function_object));

The cref call creates a constant reference, useful when your api will only accept a constant.

Accessing a reference wrapper is straight forward:

   1 A a;
   2 ReferenceWrapper<A> wrapper = ref(a);
   3 
   4 A &a_ref = wrapper.reference();
   5 A *a_ptr = wrapper.pointer();

It can also be directly passed off as the type it wraps.

Traits

Testing for reference wrapper objects can be done via the is_reference_wrapper trait.

   1 bool result = is_reference_wrapper<int>::value

This is most useful when used as a template argument metafunction.

Wiki: ecl_utilities/Tutorials/Reference Wrappers (last edited 2012-02-01 14:04:54 by DanielStonier)