Overloading — Tag dispatch

// Copyright 2014 Andrzej Krzemienski.
//
// This shows how to use tag dispatching for controlling
// which function overload to pick based on the compile-time
// properties of the argument type.

#include <cassert>
#include <type_traits>

template <typename T>
struct optional
{
  // optional always uninitialized
  explicit operator bool() const { return false; } 
  T value() const { throw int(); }
   
  template <typename U>
  T value_or(U const& v) const
  {
    return value_or_(v, std::is_convertible<U, T>{});
  }

private:

  template <typename U>
  T value_or_(U const& v, std::true_type) const
  {
    if (*this)
      return this->value();
    else
      return v;
  }
 
  template <typename F>
  T value_or_(F const& f, std::false_type) const
  {
    if (*this)
      return this->value();
    else
      return f();
  }
};

int def()
{
  return -1;
}

int main()
{
  optional<int> oi;
  assert (oi.value_or(1) == 1);
  assert (oi.value_or(&def) == -1);
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s