1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> template < typename T> void PrintValue(T val) { if constexpr (std::is_signed_v<T>) { std::cout << "signed" ; } else { std::cout << "unsigned" ; } std::cout << std::endl << val << std::endl; } |
Category Archives: C++
The sum of signed and unsigned is unsigned in C++
None of C++ compilers have heterogeneous lookup for unordered containers except MSVC
At 10/20/2020:


And std::vector
is not constexpr
yet:

And there is no text formatting also.
Coroutines:

std::chrono::days
:

Brain collapsing rules in C++
Consider the declaration of a class that contains a lambda function or a reference to it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <utility> template < class Func> struct Holder { Holder(Func && func) : m_func(std::forward<Func>(func)) { } Func m_func; }; template < class Func> auto MakeHolder(Func && func) { return Holder<Func>(std::forward<Func>(func)); } |
Why my QT app crashes at the destructor of std::thread on Android 10 devices?
I did some research on why my QT app crashes at the destructor of std::thread on Android 10 devices at the user side with the following call stack:
1 2 3 4 5 6 7 8 9 | #00 /apex/com.android.runtime/lib64/bionic/libc.so (abort+160) #01 /system/lib64/libc++.so (abort_message+232) #02 /system/lib64/libc++.so (demangling_terminate_handler()+44) #03 /system/lib64/libc++.so (std::__terminate(void (*)())+12) #04 /system/lib64/libc++.so (std::terminate()+52) #05 /system/lib64/libc++.so (std::__1::thread::~thread()+20) #06 /apex/com.android.runtime/lib64/bionic/libc.so (__cxa_finalize+212) #07 /apex/com.android.runtime/lib64/bionic/libc.so (exit+24) #08 /data/app/com.domain.myapp-Rs_sm5VrLR1Jj8QW6oYByA==/lib/arm64/libplugins_platforms_qtforandroid_arm64-v8a.so |
and figured out that its likely because std::thread destructor is being invoked while the thread is still joinable at some point of the application execution (thanks to G. M. on stackoverflow.com).
(more…)C++ binary serialization speed is comparable with std::memmove
Measuring std::memmove speed
I wrote a simple test that outputs std::memmove speed to the console:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | AWT_ATTRIBUTE( size_t , element_count, 1000000); std::unique_ptr< uint8_t > p_src( new uint8_t [element_count]); std:: memset (p_src.get(), 25u, element_count); std::unique_ptr< uint8_t > p_dst( new uint8_t [element_count]); context.out << _T( "std::memmove: " ); awl::StopWatch w; std:: memmove (p_dst.get(), p_src.get(), element_count); ReportSpeed(context, w, element_count); context.out << std::endl; |
And the similar tests for std::memset and std::vector::insert.
(more…)A funny example of C++ code that MS can compile :)
In the code below, static_assert operates on the addresses of local variables, but however MS compiles it and the assertion does not fail:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <tuple> #include <string> struct A { int a; double b; std::string c; }; void f() { A a{ 1, 3.0, "abc" }; constexpr auto t1 = std::tie(a.a, a.b, a.c); static_assert(&std::get<0>(t1) == &a.a); } |
Use the following command to compile this example:
cl /std:c++17 /EHsc a.cpp |
Basic ideas of version tolerant serialization in C++
Consider the following scenario: there was structure A in an old version of a C++ application:
1 2 3 4 5 6 | struct A { double a; int b; std::string c; }; |
An instance of A was serialized into a file in a binary format and after that the application was updated to a new version.
But in the new version of the application structure A was modified by adding fields d and e and deleting field a:
1 2 3 4 5 6 7 | struct A { int b; std::vector< int > d; bool e; std::string c; }; |
and the new version of the application needs to deserialize an instance of its new structure A from the file containing old version of A.
(more…)A simple C++ serialization framework
I implemented a simple C++ binary serialization framework that makes a structure or class serializable by adding a macro that usually takes one line of code as shown in the example below:
1 2 3 4 5 6 7 | struct A { bool x; int y; AWL_SERIALIZABLE(x, y) }; |
There is also a macro that makes a structure or a class equatable:
1 | AWL_MEMBERWISE_EQUATABLE(A) |
Parsing GUID in C++ with a regular expression
The code below demonstrates how to parse GUID in C++ using a regular expression:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #include <iostream> #include <string> #include <regex> int main() { static const std::wregex regex( L"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" ); std::wstring sample = L"850fe1da-0ea6-c1a8-9810-0c1cece30698" ; std::match_results<std::wstring::const_iterator> match; if (std::regex_match(sample, match, regex)) { std::wcout << L"matches" << std::endl; } else { std::wcout << L"does not match" << std::endl; } return 0; } |
A simple example demonstrating how std::forward works in C++
For example, std::forward comes to play if I implement a template container with two ‘insert‘ function overloads that take the parameters of type const T & and T && respectively. I implement all the private insertion logic with T&&, but when I need to know the original value type passed to ‘insert‘ method I use std::forward as shown in the example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #include <iostream> #include <string> class Value { public : Value( const char * sz) : m_s(sz) { } Value( const Value & other) : m_s(other.m_s) { std::cout << "copy constructor: " << m_s << std::endl; } Value(Value && other) : m_s(std::move(other.m_s)) { std::cout << "move constructor: " << m_s << std::endl; } const std::string & ToString() const { return m_s; } private : std::string m_s; }; |