Make std::vector of T, efficiently

What I want to briefly talk about today is likely obvious to seasoned C++ programmers, but may be of benefit for the newcomers to the language and the STL: that is how to efficiently create

std::vector
of any number of elements of type
T
, whatever
T
may be. The code is short and sweet, so let’s jump right into it:

#include 

template
inline auto make_N_of_T(std::size_t N, A&&... a)
{
	std::vector v;
	v.reserve(N);
	for(std::size_t i = 0; i < N; ++i)
		v.emplace_back(std::forward(a)...);
	return v;
}

In lines #3 and #4 we define the creation function template (

inline
because it’s likely to live in a header file and we don’t want to violate the
ODR) that says make me N instances of T and use A as parameter(s) to T’s constructor (see parameter packs and fold expressions). Next we create an instance of
std::vector<T>
in line #6 and reserve enough space for
N
instances of
T
in line #7 (without actually constructing instances of
T
yet). Line #8 is self explanatory, and the efficiency magic happens in line #9. Instead of creating a temporary instance of
T
and calling
.push_back
we instead
.emplace_back
each instance of
T
, meaning we construct it in the memory previously reserved for the elements of the container in line #7. This way we avoid unnecessary copy or move constructors (which may not even be defined for type
T
).

Before C++11 and move semantics we would have been stuck with creating an instance of

T
, then copy constructing it into every element of
std::vector<T>
, like this:

std::size_t N = 42;
vector v(N, T{});

And don’t even get me started on having to return

std::vector<T>
from a function and how costly that would have been (again, prior to the magic of move semantics)! We’re in a brave new world…

P.S. I hope you’re all doing well and staying safe in this COVID-19 world! The situation has certainly put a strain on me and a dent in my blogging frequency. I hope to return to my normal post-or-more-a-week blogging frequency soon!

Singleton Pattern

First things first: if you’re still reading this blog, thanks! I haven’t posted anything since last December; it has been a rough first half of the year: COVID-19, working from home, isolation, you know the deal, but I have not given up on blogging, just finding the time for it has been nearly impossible. I have a long list of topics I eventually want to cover but I can’t make any promises until this mad situation normalizes…

Alright then! A friend from work asked me about the Singleton Design Pattern and how to best implement it in C++. I have done it in the past but was not happy with that implementation; it insisted that the singleton class have a default constructor for example, so I started coding something that would allow non-default initialization. The first thing I came up with was a singleton template base class using the Curiously Recurring Template Pattern. It worked but it required you to declare its constructor private and declare the singleton base class a friend:

class S final : public singleton
{
public:
	~S() { cout << "~S()" << endl; }
	void foo() { cout << "S::foo() x = " << _x << endl; }
	void bar() const { cout << "S::bar() x = " << _x << endl; }

private:
	// Constructor must be private to prevent creation of instances...
	// ...except by singleton base class, which is our friend...
	friend class singleton;
	S(int x) : _x(x) { cout << "S(" << _x << ")" << endl; }
	int _x = 0;
};

This approach allowed me to separate the singleton creation

S::Create(17);
from usage
S::Instance()->foo();
but I was still bothered by the need for private constructor(s) and friendship, so I kept experimenting... I wanted a simpler solution, one that by the very nature of inheriting the singleton base class would automatically render the class non-instantiable by anyone other than the parent template:

class AS : public abstract_singleton
{
public:
	AS(int x) : _x(x) { cout << "AS(" << _x << ")" << endl; }
	~AS() { cout << "~AS()" << endl; }
	void foo() { cout << "AS::foo() x = " << _x << endl; }
	void bar() const { cout << "AS::bar() x = " << _x << endl; }

private:
	int _x = 0;
};

The name of the singleton base class probably gave away the approach, but let me explain anyway: the

abstract_singleton<AS>
base injects a pure virtual method, preventing one from creating instances of
class AS
. The parent class later erases the abstraction by implementing the private pure virtual method before creating an instance of AS (it actually creates an instance of a private type derived from AS, the compiler takes care of the rest; this works because in C++ access and visibility of a member are two distinct concepts):

struct Q : T
{
	using T::T;
	void __abstract_singleton__() override {}
};

One can of course easily defeat the mechanism by which instance creation is restricted by implementing the

void abstract_singleton() override {}
in the class meant to be a singleton. I don't think there is much that can be done about that, but if it's not done on purpose the compiler will detect attempts of creating instances and will fail with cannot instantiate an abstract class error.

Here's the example program (singleton.cpp):

#include 
#include "singleton.hpp"

using namespace std;

SINGLETON_CLASS(A) {};
SINGLETON_STRUCT(B) {};
struct C final : public singleton {};

ABSTRACT_SINGLETON_CLASS(AA) {};
ABSTRACT_SINGLETON_STRUCT(AB) {};
struct AC : public abstract_singleton {};

class S SINGLETON(S)
{
public:
	~S() { cout << "~S()" << endl; }
	void foo() { cout << "S::foo() x = " << _x << endl; }
	void bar() const { cout << "S::bar() x = " << _x << endl; }

private:
	// Constructor must be private to prevent creation of instances...
	// ...except by singleton base class, which is our friend...
	SINGLETON_FRIEND(S);
	S(int x) : _x(x) { cout << "S(" << _x << ")" << endl; }
	int _x = 0;
};

class AS ABSTRACT_SINGLETON(AS)
{
public:
	// No friendship needed if constructors are public...
	// ...but you still can't create instances of AS...
	// ...except by abstract_singleton base class...
	// ...which internally erases the abstraction...
	//ABSTRACT_SINGLETON_FRIEND(AS);
	AS(int x) : _x(x) { cout << "AS(" << _x << ")" << endl; }
	~AS() { cout << "~AS()" << endl; }
	void foo() { cout << "AS::foo() x = " << _x << endl; }
	void bar() const { cout << "AS::bar() x = " << _x << endl; }

private:
	int _x = 0;
};

int main()
{
	S::Create(17);
	//S s(17); // Compile-time error, can't create instances...
	try { S::Create(17); }
	catch(exception& e) { cout << e.what() << endl; }
	//*S::Instance() = *S::Instance(); // Compile-time error, can't copy/move singletons...
	S::Instance()->foo();
	S::Instance()->bar();

	AS::Create(20);
	//AS s(20); // Compile-time error, can't create instances...
	try { AS::Create(20); }
	catch(exception& e) { cout << e.what() << endl; }
	//*AS::Instance() = *AS::Instance(); // Compile-time error, can't copy/move singletons...
	AS::Instance()->foo();
	AS::Instance()->bar();

	cout << "Done!" << endl;
}

And the complete listing (singleton.hpp):

#include 
#include 
#include 
#include 

template
class singleton
{
public:
	template
	static void Create(Args&&... args)
	{
		static std::mutex s_lock;
		std::scoped_lock lock(s_lock);

		if(!s_instance) s_instance.reset(new T(std::forward(args)...));
		else throw std::logic_error("This singleton has already been created!");
	}

	static T* Instance() noexcept { return s_instance.get(); }

protected:
	singleton() = default;
	singleton(const singleton&) = delete;
	singleton(singleton&&) = delete;
	singleton& operator = (const singleton&) = delete;
	singleton& operator = (singleton&&) = delete;
	~singleton() = default;

private:
	using storage_t = std::unique_ptr;
	inline static storage_t s_instance = nullptr;
};

#define SINGLETON(T) final : public singleton
#define SINGLETON_CLASS(C) class C SINGLETON(C)
#define SINGLETON_STRUCT(S) struct S SINGLETON(S)
#define SINGLETON_FRIEND(T) friend class singleton

template
class abstract_singleton
{
public:
	template
	static void Create(Args&&... args)
	{
		static std::mutex s_lock;
		std::scoped_lock lock(s_lock);

		struct Q : T
		{
			using T::T;
			void __abstract_singleton__() override {}
		};

		if(!s_instance) s_instance.reset(new Q(std::forward(args)...));
		else throw std::logic_error("This abstract singleton has already been created!");
	}

	static T* Instance() noexcept { return s_instance.get(); }

protected:
	abstract_singleton() = default;
	abstract_singleton(const abstract_singleton&) = delete;
	abstract_singleton(abstract_singleton&&) = delete;
	abstract_singleton& operator = (const abstract_singleton&) = delete;
	abstract_singleton& operator = (abstract_singleton&&) = delete;
	virtual ~abstract_singleton() = default;

private:
	using storage_t = std::unique_ptr;
	inline static storage_t s_instance = nullptr;

	virtual void __abstract_singleton__() = 0;
};

#define ABSTRACT_SINGLETON(T) : public abstract_singleton
#define ABSTRACT_SINGLETON_CLASS(C) class C ABSTRACT_SINGLETON(C)
#define ABSTRACT_SINGLETON_STRUCT(S) struct S ABSTRACT_SINGLETON(S)
#define ABSTRACT_SINGLETON_FRIEND(T) friend class abstract_singleton