C++



C++ “The Language of System Programming”

This tutorial is about key features of C++ including those supported from C++11, C++14, C++17, C++20, or C++23. On purpose, you may look at this blog, which sums up the key novelties brought out by C++11. Other amendments/extensions are C++14 here, C++17 here (and detailed explanations there), C++20 here, and C++23 here.

C++ does not actually have competitors, except its father the C programming language, and, maybe, its son the Rust programming language.

C++ positioning in programming languages competition

First rose LisP, Pascal, CoBOL, ForTran, Beginner's All-purpose Symbolic Instruction Code -BASIC-… and later on… C, C++, Java, JavaScript, Python… The way languages popularity is nowadays measured depends upon data extracted from the Web. For example, the TIOBE Index proposes a ranking of languages.

Ranking in 2024

Most wanted…

Energy efficiency here

Styles of programming

Rule(s)

C++ Topics
C++ “Politician” exercise

Politicians deal with “realizations” (bridges, museums…) for their term. As creators, their responsibility is high. Later, as election losers, they keep authorship of realizations, but replacing politicians inherit their responsibility at a lower level. This is especially true when realizations are not yet finished and budgets are exceeded!

The C++ program imitates this behavior: Politician class owns std::list<Realization> _realizations; as attribute. The main function transfers realizations from loser to winner by copy.

  1. Revise the get function so that it moves (instead of copies) realizations. Take the advantage of the move semantics to change responsibility from Responsibility::High to Responsibility::Low.
  2. What about storage optimization of name attribute within to Realization class? const std::string& versus const std::string_view here
#include <iostream>
#include <list>
#include <string>

class Realization {
public:
	const std::string name;
	enum class Responsibility : char {
		High = 'H',
		Low = 'L'
	};
	const Responsibility responsibility;
	enum class Type : char {
		Bridge = 'B',
		Museum = 'M' // Etc.
	};
	const Type type;
public:
	Realization(const std::string&, const Type = Type::Bridge, const Responsibility = Responsibility::High);
	Realization(const std::string&&, const Type, const Responsibility) = delete;
	Realization(const Realization&); // Copy constructor or initialization...
};
Realization::Realization(const std::string& name, const Type type, const Responsibility responsibility) : name(name), responsibility(responsibility), type(type) {}
Realization::Realization(const Realization& realization) : Realization(realization.name, realization.type, realization.responsibility) { // Constructor delegation...
	std::cout << "Copy constructor... " << name << std::endl;
}

class Politician {
private:
	// 'The C++ Standard forbids containers of const elements because allocator<const T> is ill-formed.':
	// std::list<const Realization> _realizations;
	std::list<Realization> _realizations;
public:
	// https ://en.cppreference.com/w/cpp/utility/initializer_list
	// 'std::initializer_list<T>' cannot have lvalues or rvalues: 
	Politician(const std::initializer_list<Realization>&);
	Realization& get(const std::string&);
	std::list<Realization>::size_type count() const;
};
Politician::Politician(const std::initializer_list<Realization>& realizations) {
	// for (const Realization& r : realizations) // 'r' is not copied at all...
		// _realizations.push_back(r); // 'r' is copied...
	for (auto&& realization : realizations) { // 'realization' is inferred as 'Realization&' because 'std::initializer_list<Realization>' owns 'Realization' objects...
		std::cout << "Within 'push_back'... "; _realizations.push_back(realization); // 'realization' is copied...
	}
}
Realization& Politician::get(const std::string& name) {
	for (std::list<Realization>::iterator i = _realizations.begin(); i != _realizations.end(); i++)
		if (name == (*i).name)
			return *i; // Copy...
	throw "Not found";
}
std::list<Realization>::size_type Politician::count() const {
	return _realizations.size();
}

int main() {
	const std::string b = "Bridge B";
	const std::string m = "Museum M";
	// Compilation error, 'delete' avoids this form:
	// Realization&& Museum_M = Realization("Museum M", Realization::Type::Museum);
	Realization&& Museum_M = Realization(m, Realization::Type::Museum);

	Politician loser{ { Museum_M, Realization(b)} }; // 'Museum_M' is copied while 'Realization(b)' is not...
	std::cout << "'loser.count()': " << loser.count() << std::endl;
	Politician winner{ loser.get(m), loser.get(b) };
	std::cout << "'winner.count()': " << winner.count() << std::endl;

	return 0;
}