Implementing operator<() for strict weak ordering

Overload113Cover
The latest edition of Overload Magazine (a publication by the ACCU) includes a recipe for implementing operator<, as is often required when you want store some class in an STL associative container.

bool operator<( const T& rhs ) const
{
if ( a != rhs.a ) return a < rhs.a;
if ( b != rhs.b) return b < rhs.b;
...
return false;
}

This assumes that operator!= exists on that class and in my view muddies the waters between equivalence (the property you test in a std::set or std::map with operator<) and equality (the test in std::vector or std::list with operator==). Of course, if operator== exists, you can easily amend the recipe accordingly, but again neither operator== nor operator!= have default implementations so may not be provided.

Where necessary, you can fall back onto this more verbose recipe:

bool operator <(const T& rhs) const
{
  if ( a < rhs.a )
    return true;
  else if (rhs.a < a)
    return false;

  if ( b < rhs.b)
    return true;
  else if (rhs.b < b)
    return false;

  // repeat for all child elements c, d, e etc
  return false;
}

Leave a comment

Filed under C++ Code

Bjarne Stroustrup’s Tour of C++

I’m reading through Bjarne Stroustrup’s Tour of C++, which Addison-Wesley have graciously allowed him to post ahead of its inclusion in the fourth edition of The C++ Programming Language.

stroustrup

It starts with The Basics. It was refreshing to see new features of C++11 introduced alongside the most rudimentary aspects of the language – rather than being viewed as a whole new language that teams might choose to adopt/ignore. I’m sure if you start learning C++ today, features such as enum class, auto, constexpr will seem natural, begging the question “What did you do without them?”.

I thought this code snippet was especially cute:

for (auto x : {10,21,32,43,54,65})
    std::cout << x << '\n';

I’m used to writing code in F# like this,

[| 10; 21; 32; 43; 54; 65 |] 
  |> Array.iter (fun i -> printf "%d\n" i)

but it’s great to see such concise code in C++ at well.

The second part concerns abstractions. This includes summaries of copy and move semantics. This note on move semantics is helpful because many explanations focus on how to move data into a new instance of a class rather than the state in which to leave the old object:

After a move, an object should be in a state that allows a destructor to be run. Typi- cally, we should also allow assignment to a moved-from object

Preventing copy and move:

Using the default copy or move for a class in a hierarchy is typically a disaster: Given only a pointer to a base, we simply don’t know what members the derived class has (§3.3.3), so we can’t know how to copy them. So, the best thing to do is usually to delete the default copy and move operations; that is, to eliminate to default definitions of those two operations

where C++11 provides the delete annotation to tell the compiler not to write a default copy/move operation, but you could follow today’s practice and declare it private and omit the implementation until your compiler catches up.

If you need to copy an object in a class hierarchy, write some kind of clone function. [Note that] a move operation is not implicitly generated for a class where the user has explicitly declared a destructor. Furthermore, the generation of copy operations are deprecated in this case. This can be a good reason to explicitly define a destructor even where the compiler would have implicitly provided one.

There are also useful examples of where to use type aliasing, for example this one that uses the assumption that STL containers provide a value_type alias (or typedef):

template<typename C>
using Element_type = typename C::value_type; 

template<typename Container> void algo(Container& c)
{
  Vector<Element_type<Container>> vec;
  // ... 
}

You can also use aliasing to define new templates by binding arguments on existing templates:

template<typename Value>
using String_map = Map<string,Value>;

String_map<int>m; //alias for Map<string,int>

Part three is about algorithms and containers.

The example for how to write operator>>(), read from, is particularly verbose – I’m sure it would have been better to show a regex solution alongside. Worth a look anyway for this mechanism for indicating a streaming failure (typically I would throw an exception):

is.setf(ios_base::failbit);

Similarly, I hadn’t realised before that range-checked random access to a std::vector was possible via the at(size_t i) method:

T& operator[](int i) { return vector::at(i); } // range-checked

The final part is about concurrency and utilities.

One of the main utilities now available in C++11 is std::shared_ptr (which was sorely lacking from the previous standard).  However, Stroustrup hints that in many cases it’s sufficient to create an object on the stack with a local variable:

Unfortunately, overuse of new (and of pointers and references) seems to be an increasing problem.

When you do need to manage heap objects, std::unique_ptr is very lightweight with no space or time overhead compared to a built-in pointer.  You can pass or return unique_ptr’s in or out of functions, because the implementation uses move semantics (whereas std::shared_ptr is copied).

One concurrency topic that always causes problems is how to define a convention between locks so that deadlock cannot occur due to acquiring the locks in the wrong order.  There’s a neat example of how to avoid that:

// Initialise lock guards with their mutexes, but don't lock yet
std::lock_guard<std::mutex> lock1(mutex1, defer_lock);
std::lock_guard<std::mutex> lock2(mutex2, defer_lock);
std::lock_guard<std::mutex> lock3(mutex3, defer_lock);
// other preparation
std::lock( lock1, lock2, lock3 );
// Implicitly release all mutexes when locks go out of scope.

Stroustrup also introduces the concepts of futures and promises:

The important point about future and promise is that they enable a transfer of a value between two tasks without explicit use of a lock; “the system” implements the transfer efficiently.

The absence of locks is key and is also mentioned when introducing std::packaged_task and std::async.  This section might be better written in reverse, with the simpler async concept introduced first and locks/mutexes in context as the advanced technique.

Under <utilities>, a boon is likely to be std::tuple, a heterogenous sequence of elements (I’ve added the use of std::tie to show how to unpack the values):

auto myTuple = std::make_tuple(std::string("Hello"), 10, 1.23);
std::string a;
int b;
double c;
std::tie( a, b, c ) = myTuple;

I wouldn’t use std::tuple in an externally visible interface, but it’s useful to avoid defining types for passing multiple return values.

I like this example of using the new standard <random> library to simulate a die:

using my_engine = default_random_engine; // type of engine
using my_distribution = uniform_int_distribution<>; 
my_engine re {}; // the default engine
my_distribution one_to_six {1,6}; 
auto dice = bind(one_to_six,re); // make a generator
int x = dice(); // roll the dice: x becomes a value in [1:6]

 

Leave a comment

Filed under C++

The Rise of Dark Pools

TheTradeNews.com reports that institutional traders are leaving traditional displayed market venues for dark pools:

Experts like Justin Schack, partner and managing director at Rosenblatt Securities, has seen the overall market share of dark liquidity pools rise from 6.55% in 2008, just after the adoption of Regulation NMS and the introduction of its Trade Reporting Facility – a source of off-exchange trading data – to 13.36% at the end of 2012.

However, fleeing to dark pools wasn’t enough – other strategies have been put in place to mitigate against the high-frequency traders:

Some dark liquidity pool operators responded to this change in order size by introducing ‘order bunching’, where they would aggregate a series of smaller orders to create the other half of an institutional trade. In theory, an institutional trade could interact with four or five high-frequency traders on a 2,000-share trade instead of a single high-frequency trader in a 200-share trade.

Other dark pools define a variety of trader profiles and are allowing participants to specify with which profiles they are prepared to trade.

Leave a comment

Filed under Finance

Using the compiler to answer calling convention questions

Raymond Chen points out that you can help yourself by using the compiler to output assembly listings which can help to answer questions such as which parameter comes first under the current calling convention.

Leave a comment

Filed under C++

Explicit user-defined conversion operators

You can now mark user-defined conversion operators as explicit:

        explic­it oper­a­tor bool() const;

This is an improvement over previous idioms that have been employed to avoid a class of bugs that occur when a type is inadvertently converted.

Leave a comment

Filed under C++

Online C++ Compilers

Today I took a look at some Online C++ compilers – this would have been very useful when checking portability of some code in my recent post on C++11 Concurrency.

First, here’s LiveWorkspace.org which makes g++ 4.72 and 4.8 available as well as clang 3.2:

MutableReferenceMemberClang

Second, Rise4Fun allows you to try Visual Studio:
MutableReferenceMemberVS

As anticipated, the Counter class (which contains a mutable member of type int&) compiles under Visual Studio, but doesn’t under clang 3.2 or gcc (which is correct according to the C++ standard). What’s great about LiveWorkspace is how quickly you can switch between compilers to see how they like the same code. For example, the amended code that treats int& as a template parameter compiles under g++ 4.7.2 and 4.8, but doesn’t under clang 3.2:

#include <iostream>

template<typename T>
class Counter
{
  mutable T m_t;
public:
  Counter(T t) : m_t(t){}
  void Increment() const { ++m_t; }
};

int main()
{
  int count = 0;
  Counter<int&> counter(count);
  counter.Increment();
  std::cout << count << "\n";
  return 0;
}

Leave a comment

Filed under C++

Excel and The London Whale

The problems of using Excel within financial institutions are well-known – the control risks are huge because it’s so easy for a rogue trader to manually edit trade data/market data and re-save the sheet. This article describes the role Excel played in under-estimating the risks involved in financing The London Whale’s trading strategies:

JPMor­gan’s Chief Invest­ment Office need­ed a new value-at-risk (VaR) model for the syn­thet­ic cred­it port­fo­lio (the one that blew up) and assigned a quan­ti­ta­tive whiz (“a London-based quan­ti­ta­tive expert, math­e­mati­cian and model devel­op­er” who pre­vi­ous­ly worked at a com­pa­ny that built ana­lyt­i­cal mod­els) to cre­ate it. The new model “oper­at­ed through a series of Excel spread­sheets, which had to be com­plet­ed man­u­al­ly, by a process of copy­ing and past­ing data from one spread­sheet to another.”

Another question is, how do you test a spreadsheet? And how do you re-use fragments of a sheet?

the spread­sheets that peo­ple cre­ate with Excel are incred­i­bly frag­ile. There is no way to trace where your data come from, there’s no audit trail (so you can over­type num­bers and not know it), and there’s no easy way to test spread­sheets

Leave a comment

Filed under Finance

Qualities of Uber-Productive people

Great article on how to achieve high productivity.

Productive people aren’t braver than others; they just find the strength to keep moving forward. They realize fear is paralyzing while action creates confidence and self-assurance.

I subscribe to the school of thought that, in order to finish a project, you have to keep starting – to get over the fear of imperfection, you don’t focus on completion, but focus on beginning again and again.

Think about a time you put off a task, finally got started, and then, once into it, thought, “I don’t know why I kept putting this off–it’s going really well. And it didn’t turn out to be nearly as hard as I imagined.”

Read more: http://www.inc.com/jeff-haden/7-qualities-of-uber-productive-people.html#ixzz2KoR5fDv8

Leave a comment

Filed under Soft skills

Introduction to C++11 Concurrency

Marius Bancila wrote a neat introduction to C++11 concurrency.

Leave a comment

Filed under C++

Apple SmartWatch – yes please!

When I awoke this morning, I didn’t know that I wanted a smart watch. Having read this article, though, I’ve realised my set of gadgetry won’t be complete until I get one. The reviews of the currently available smart watches weren’t very complimentary, so I’ll wait to see what Apple come up with.

Leave a comment

Filed under Technology