Guide: Reference Wrappers

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.

class A {
public:
    template <typename T>
    void f(T i) { cout << "Not a reference input" << endl; }

    template <typename T>
    void f(T &i) { cout << "A reference input" << endl; }
}

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.

CompilingLinking

Include the following at the top of any translation unit that uses these container classes.

#include <ecl/utilities.hpp>

using ecl::ReferenceWrapper
using ecl::ref
using ecl::cref
using ecl::addressOf

You will also need to link to -lecl_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.

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:

A a;
ReferenceWrapper<A> wrapper = ref(a);

A &a_ref = wrapper.reference();
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.

bool result = is_reference_wrapper<int>::value

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

Examples



ecl_utilities
Author(s): Daniel Stonier
autogenerated on Sun Oct 5 2014 23:35:35