1. Anteru
  2. c++11-samples

Commits

Matthäus G. Chajdas  committed f67a6e4

Initial commit.

  • Participants
  • Branches default

Comments (0)

Files changed (21)

File auto_ref.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+struct Object
+{
+	Object (const Object& object)
+	{
+		std::cout << "Copy-Constructor" << std::endl;
+	}
+
+	Object ()
+	{
+		std::cout << "Constructor" << std::endl;
+	}
+
+	Object& operator= (const Object& rhs)
+	{
+		std::cout << "Assignment" << std::endl;
+		return *this;
+	}
+};
+
+class Container
+{
+public:
+	const Object& Get () const
+	{
+		return object_;
+	}
+
+private:
+	Object object_;
+};
+
+int main ()
+{
+	std::cout << "Start" << std::endl;
+	Container c;
+
+	std::cout << "---" << std::endl;
+	auto o = c.Get ();
+
+	std::cout << "---" << std::endl;
+	const auto& oc = c.Get ();
+
+	std::cout << "End" << std::endl;
+}

File auto_simple.cpp

View file
  • Ignore whitespace
+#include <vector>
+#include <iostream>
+
+int main ()
+{
+	std::vector<std::vector<std::pair<int, int>>> nestedVector;
+
+	nestedVector.push_back (std::vector<std::pair<int, int>> ());
+	nestedVector [0].push_back (std::make_pair (23, 42));
+
+	for (auto it = nestedVector.begin (), end = nestedVector.end (); it != end; ++it) {
+		for (auto jit = it->begin (), jend = it->end (); jit != jend; ++jit) {
+			std::cout << jit->first << ", " << jit->second << std::endl;
+		}
+	}
+}

File bind.cpp

View file
  • Ignore whitespace
+#include <functional>
+#include <iostream>
+
+void Process (const int count,
+	std::function<void (const int processed)> callback)
+{
+	for (int i = 0; i < count; ++i) {
+		callback (i);
+	}
+}
+
+void PrintProgress (const int total, const int finished)
+{
+	std::cout << finished << "/" << total << std::endl;
+}
+
+int main ()
+{
+	Process (23, std::bind (PrintProgress, 23, std::placeholders::_1));
+}

File bind_member.cpp

View file
  • Ignore whitespace
+#include <functional>
+#include <iostream>
+
+void Process (const int count,
+	std::function<void (const int processed)> callback)
+{
+	for (int i = 0; i < count; ++i) {
+		callback (i);
+	}
+}
+
+struct ProgressHandler
+{
+	ProgressHandler (const int total)
+	: total_ (total)
+	{
+	}
+
+	void Print (const int finished) const
+	{
+		std::cout << finished << "/" << total_ << std::endl;
+	}
+
+	int total_;
+};
+
+int main ()
+{
+	ProgressHandler progress (23);
+	// Bind to member function "Print" of object instance "progress"
+	// First parameter is passed through
+	Process (23, std::bind (
+		&ProgressHandler::Print, &progress, std::placeholders::_1));
+}

File decltype.cpp

View file
  • Ignore whitespace
+#include <iostream>
+#include <type_traits>
+
+template <typename T>
+class Wrapper
+{
+private:
+	T t_;
+
+public:
+	Wrapper (const T t)
+	: t_ (t)
+	{
+	}
+
+	typedef T Type;
+
+	template <typename U>
+	auto operator* (const U u) -> Wrapper<decltype (T() * U())>
+	{
+		typedef decltype(T() * U()) ResultType;
+
+		const auto result = u * t_;
+		return Wrapper<ResultType> (result);
+	}
+
+	T Get () const
+	{
+		return t_;
+	}
+};
+
+int main ()
+{
+	Wrapper<int> iWrap (23);
+	// result is now of type Wrapper<float>
+	const auto result = iWrap * 2.37f;
+
+	std::cout << result.Get () << std::endl;
+}

File def_del.cpp

View file
  • Ignore whitespace
+class Test
+{
+public:
+	Test () = default;
+	Test (const Test& t) = delete;
+	Test& operator= (const Test& t) = delete;
+};
+
+int main ()
+{
+	Test t;
+	// nope
+	t = Test ();
+}

File function.cpp

View file
  • Ignore whitespace
+#include <functional>
+#include <iostream>
+
+void Process (const int count,
+	std::function<void (const int total, const int processed)> callback)
+{
+	for (int i = 0; i < count; ++i) {
+		callback (count, i);
+	}
+}
+
+void PrintProgress (const int total, const int finished)
+{
+	std::cout << finished << "/" << total << std::endl;
+}
+
+int main ()
+{
+	Process (23, PrintProgress);
+}

File init_list.cpp

View file
  • Ignore whitespace
+#include <initializer_list>
+#include <iostream>
+
+template <typename T>
+class Container
+{
+public:
+	Container (const std::initializer_list<T>& d)
+	: data_ (new T [d.size ()])
+	, count_ (d.size ())
+	{
+		std::copy (d.begin (), d.end (), data_);
+	}
+
+	~Container ()
+	{
+		delete data_;
+	}
+
+	const T* begin () const
+	{
+		return data_;
+	}
+
+	const T* end () const
+	{
+		return data_ + count_;
+	}
+
+private:
+	T* data_;
+	size_t count_;
+};
+
+int main ()
+{
+	Container<int> c ({0, 8, 1, 5});
+
+	for (auto i : c) {
+		std::cout << i << std::endl;
+	}
+}

File lambda_capture.cpp

View file
  • Ignore whitespace
+#include <iostream>
+#include <vector>
+#include <functional>
+
+void Process (const int count,
+	std::function<void (const int item)> func)
+{
+	for (int i = 0; i < count; ++i) {
+		func (((i << 3) + 1317));
+	}
+}
+
+void Print (const char* message, const std::vector<int>& v)
+{
+	std::cout << message << std::endl;
+
+	for (auto it = v.begin (), end = v.end (); it != end; ++it) {
+		std::cout << *it << std::endl;
+	}
+}
+
+int main ()
+{
+	std::vector<int> container;
+
+	Process (4, [&container] (const int i) -> void {
+		container.push_back (i);
+	});
+
+	Print ("Container-by-ref", container);
+
+	container.clear ();
+
+	Process (4, [container] (const int i) mutable -> void {
+		container.push_back (i);
+	});
+
+	Print ("Container-by-copy", container);
+
+	container.clear ();
+
+	Process (4, [&] (const int i) -> void {
+		container.push_back (i);
+	});
+
+	Print ("Ref-all", container);
+}

File lambda_simple.cpp

View file
  • Ignore whitespace
+#include <vector>
+#include <iostream>
+#include <string>
+
+int main ()
+{
+	std::vector<std::string> items;
+
+	items.push_back ("/foo/bar");
+	items.push_back ("/foo/baz");
+	items.push_back ("/tmp/item");
+
+	items.erase (std::remove_if (items.begin (), items.end (),
+		[] (const std::string& s) -> bool {
+			return s.compare (0, 4, "/foo") == 0;
+		}), items.end ());
+
+	for (auto it = items.begin (), end = items.end (); it != end; ++it) {
+		std::cout << *it << std::endl;
+	}
+}

File nullptr.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+void foo (void* f)
+{
+	std::cout << "void foo (void*)" << std::endl;
+}
+
+void foo (int f)
+{
+	std::cout << "void foo (int)" << std::endl;
+}
+
+int main ()
+{
+	foo (nullptr);
+}

File range_for.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+int main ()
+{
+	const int arr [] = {1, 3, 3, 7};
+
+	for (auto i : arr) {
+		std::cout << i << std::endl;
+	}
+}

File rvalue_ref.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+#define ALLOW_MOVE 1
+
+class Object
+{
+public:
+	Object (const Object& object)
+	: count_ (object.count_)
+	{
+		data_ = new int [count_];
+
+		for (int i = 0; i < count_; ++i) {
+			data_ [i] = object.data_ [i];
+		}
+
+		std::cout << "Copy-Constructor" << std::endl;
+	}
+
+#if ALLOW_MOVE
+	Object (Object&& object)
+	: count_ (object.count_)
+	{
+		data_ = object.data_;
+		object.count_ = 0;
+		object.data_ = nullptr;
+
+		std::cout << "Move-Constructor" << std::endl;
+	}
+#endif
+
+	Object (const int count)
+	: count_ (count)
+	{
+		data_ = new int [count];
+
+		std::cout << "Constructor" << std::endl;
+	}
+
+	Object& operator= (const Object& rhs)
+	{
+		delete [] data_;
+		count_ = rhs.count_;
+		data_ = new int [count_];
+
+		for (int i = 0; i < count_; ++i) {
+			data_ [i] = rhs.data_ [i];
+		}
+
+		std::cout << "Copy-Assignment" << std::endl;
+		return *this;
+	}
+
+#if ALLOW_MOVE
+	Object& operator= (Object&& rhs)
+	{
+		delete [] data_;
+		count_ = rhs.count_;
+		data_ = rhs.data_;
+
+		rhs.data_ = nullptr;
+		rhs.count_ = 0;
+
+		std::cout << "Move-Assignment" << std::endl;
+		return *this;
+	}
+#endif
+
+	~Object ()
+	{
+		delete [] data_;
+	}
+
+	int GetCount () const
+	{
+		return count_;
+	}
+
+	int operator [] (const int index) const
+	{
+		return data_ [index];
+	}
+
+	int& operator [] (const int index)
+	{
+		return data_ [index];
+	}
+
+private:
+	int* data_;
+	int count_;
+};
+
+Object MakeObject ()
+{
+	Object o (4);
+	o [0] = 3;
+	o [1] = 5;
+	o [2] = 7;
+	o [3] = 11;
+
+	return o;
+}
+
+int main ()
+{
+	Object o (23);
+
+	o = MakeObject ();
+}

File rvalue_ref_fwd.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+class BigFatData
+{
+};
+
+class DataProcessor
+{
+public:
+	void Consume (BigFatData&& data)
+	{
+		std::cout << "Win" << std::endl;
+	}
+
+	void Consume (const BigFatData& data)
+	{
+		std::cout << "Fail" << std::endl;
+	}
+};
+
+void Process (DataProcessor& proc, BigFatData&& data)
+{
+	// Must use forward here, otherwise, the const T& overload is called
+	proc.Consume (std::forward<BigFatData> (data));
+}
+
+BigFatData GetData ()
+{
+	return BigFatData ();
+}
+
+int main ()
+{
+	DataProcessor proc;
+	Process (proc, GetData ());
+}

File rvalue_ref_move.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+class Object
+{
+public:
+	Object (const Object& object)
+	{
+		std::cout << "Copy-Constructor" << std::endl;
+	}
+
+	Object (Object&& object)
+	{
+		std::cout << "Move-Constructor" << std::endl;
+	}
+
+	Object ()
+	{
+		std::cout << "Constructor" << std::endl;
+	}
+
+	Object& operator= (const Object& rhs)
+	{
+		std::cout << "Copy-Assignment" << std::endl;
+		return *this;
+	}
+
+	Object& operator= (Object&& rhs)
+	{
+		std::cout << "Move-Assignment" << std::endl;
+		return *this;
+	}
+
+	~Object ()
+	{
+		std::cout << "Destructor" << std::endl;
+	}
+};
+
+void Consume (Object&& object)
+{
+	Object obj (std::forward<Object> (object));
+}
+
+int main ()
+{
+	Object o;
+
+	// Must use std::move here to actually move the object
+	Consume (std::move (o));
+
+	std::cout << "After consume" << std::endl;
+}

File static_assert.cpp

View file
  • Ignore whitespace
+int main ()
+{
+	static_assert (sizeof (void*) == 4, "void* must be 4 bytes large");
+}

File unique_ptr.cpp

View file
  • Ignore whitespace
+#include <memory>
+
+struct ILogTarget
+{
+	virtual ~ILogTarget ()
+	{
+	}
+};
+
+ILogTarget* CreateFileTarget ()
+{
+	class FileTarget : public ILogTarget
+	{
+
+	};
+
+	return new FileTarget ();
+}
+
+ILogTarget* CreateConsoleTarget ()
+{
+	class ConsoleTarget : public ILogTarget
+	{
+
+	};
+
+	return new ConsoleTarget ();
+}
+
+int main ()
+{
+	// ohoh
+	auto logTarget = CreateConsoleTarget ();
+
+	// better
+	std::shared_ptr<ILogTarget> logSP (CreateConsoleTarget ());
+
+	// Best solution: See unique_ptr_fix
+}

File unique_ptr_fix.cpp

View file
  • Ignore whitespace
+#include <memory>
+
+struct ILogTarget
+{
+	virtual ~ILogTarget ()
+	{
+	}
+};
+
+std::unique_ptr<ILogTarget> CreateFileTarget ()
+{
+	class FileTarget : public ILogTarget
+	{
+
+	};
+
+	return std::unique_ptr<ILogTarget> (new FileTarget ());
+}
+
+std::unique_ptr<ILogTarget> CreateConsoleTarget ()
+{
+	class ConsoleTarget : public ILogTarget
+	{
+
+	};
+
+	return std::unique_ptr<ILogTarget> (new ConsoleTarget ());
+}
+
+int main ()
+{
+	// ok
+	auto logTarget = CreateConsoleTarget ();
+
+	// also possible
+	std::shared_ptr<ILogTarget> sharedLog (CreateConsoleTarget ());
+}

File unique_ptr_fwd.cpp

View file
  • Ignore whitespace
+#include <memory>
+#include <iostream>
+
+class Object
+{
+public:
+	Object (const Object& object)
+	{
+		std::cout << "Copy-Constructor" << std::endl;
+	}
+
+	Object (Object&& object)
+	{
+		std::cout << "Move-Constructor" << std::endl;
+	}
+
+	Object ()
+	{
+		std::cout << "Constructor" << std::endl;
+	}
+
+	Object& operator= (const Object& rhs)
+	{
+		std::cout << "Assignment" << std::endl;
+		return *this;
+	}
+};
+
+// Use variadic template to perfect forward all parameters
+template <typename T, typename U>
+std::unique_ptr<T> make_unique (U&& u)
+{
+	return std::unique_ptr<T> (new T (std::forward<U> (u)));
+}
+
+Object MakeObject ()
+{
+	return Object ();
+}
+
+int main ()
+{
+	auto up = make_unique<Object> (MakeObject ());
+}

File unordered_map.cpp

View file
  • Ignore whitespace
+#include <unordered_map>
+#include <iostream>
+
+struct MyType
+{
+	MyType (const int a, const int b)
+	: a (a)
+	, b (b)
+	{
+	}
+
+	bool operator== (const MyType& rhs) const
+	{
+		return a == rhs.a && b == rhs.b;
+	}
+
+	int a, b;
+};
+
+std::ostream& operator<< (std::ostream& str, const MyType& t)
+{
+	return str << t.a << ", " << t.b;
+}
+
+namespace std {
+	template <>
+	struct hash <MyType>
+	{
+		size_t operator () (const MyType& t) const
+		{
+			// or use boost::hash_combine
+			return std::hash<int> () (t.a) ^ std::hash<int> () (t.b);
+		}
+	};
+}
+
+int main ()
+{
+	std::unordered_map<MyType, int> hashMap;
+
+	hashMap [MyType (23, 12)] = 1;
+	hashMap [MyType (42, 17)] = 2;
+	hashMap [MyType (13, 37)] = 3;
+	hashMap [MyType (47, 11)] = 4;
+
+	for (auto it = hashMap.begin (), end = hashMap.end (); it != end; ++it) {
+		std::cout << it->first << " : " << it->second << std::endl;
+	}
+}

File variadic.cpp

View file
  • Ignore whitespace
+#include <iostream>
+
+void Printf (std::ostream& str)
+{
+	str << std::endl;
+}
+
+template <typename T, typename ...Params>
+void Printf (std::ostream& str, const T& value, Params&&... params)
+{
+	str << value << " ";
+	Printf (str, params...);
+}
+
+int main ()
+{
+	Printf (std::cout, "bla", "foo", 23);
+}