Skip to Content [alt-c]

Andrew Ayer

Sections

You are here: Andrew's SiteProjectsC++ Templates

Useful C++ Templates

concat_string (C++11)

This is a useful variadic template function that returns the concatenation of the std::string representations of its arguments. It's more efficient than the + operator because it doesn't create temporaries, and more general because the arguments can be any type (as long as they can be written to a std::ostream).

Examples

  • std::string date_string = concat_string(year, '-', month, '-', day);
  • unlink(concat_string("/var/tmp/user-", getuid(), ".lock").c_str());
  • throw Error(concat_string("Unable to open ", path, ": ", errno));

Implementation

#include <sstream> inline void build_string (std::ostream& o) { } template<class First, class... Rest> inline void build_string (std::ostream& o, const First& value, const Rest&... rest) { o << value; build_string(o, rest...); } template<class... T> std::string concat_string (const T&... value) { std::ostringstream o; build_string(o, value...); return o.str(); }

make_unique_ptr and unique_new (C++11)

make_unique_ptr takes a bare pointer as an argument and returns a std::unique_ptr for it. The following are equivalent:

  • std::unique_ptr<std::vector<int>>(new std::vector<int>(10))
  • make_unique_ptr(new std::vector<int>(10))

As you can see, make_unique_ptr is much shorter because you don't need to specify the type for the unique_ptr (as make_unique_ptr deduces it). A function like this should really be in the standard library (to complement std::make_pair and std::make_tuple).

Implementation

#include <memory> template<class T> inline std::unique_ptr<T> make_unique_ptr (T* p) { return std::unique_ptr<T>(p); }

unique_new is like the new operator except it returns a unique_ptr. It's parameterized by the object type and perfectly forwards is arguments to the type's constructor. The following are all equivalent:

  • std::unique_ptr<std::vector<int>>(new std::vector<int>(10))
  • make_unique_ptr(new std::vector<int>(10))
  • unique_new<std::vector<int>>(10);

Using unique_new saves you even more typing than make_unique_ptr, but it has limitations: if the constructor is private, it doesn't work. That's because new is technically being called from inside unique_new, not from where unique_new is called.

Implementation

#include <memory> template <class T, class... Arg> inline std::unique_ptr<T> unique_new (Arg&&... args) { return std::unique_ptr<T>(new T(std::forward<Arg>(args)...)); }