-
after upgrading cmake version, it may need to flush some cache under project root directory with the command below:
hash -r
-
when passing a member function as a callable argument, remember that the first parameter of
std::function
should be the class containing that member function and the callable argument should be the address of the member function:explicit Session(tcp::socket socket, std::function<void(Server &, const std::string &)> deliverCallback); Session s(std::move(socket), &Server::Deliver);
What's more, if the member function is declared as
const
, the first parameter ofstd::function
should also beconst
. -
when using
async_read
instead ofasync_read_some
, it will block if the current read stream cannot fill theasio::buffer
. that is to say, if the length of theasio::buffer
is too large, theasync_read
may block until an EOF. -
in the implementation of asio's
async_
functions, it seems that you cannot capture a char* in the lambda of callback. instead, aself
got fromshared_from_this()
should be captured. -
bad_weak_ptr
could happen if usingshared_from_this()
on an object which has noshared_ptr
pointing to it yet. -
std::*_pointer_cast
could only be applied toshared_ptr
(because copy operation ofunique_ptr
is deleted). if you must cast the type of aunique_ptr
, use below:dst.reset(dynamic_cast<A *>(src.release()));
note that
release()
should be used here instead ofget()
because you need to release the ownership of managed object bysrc
, otherwisedst
would gain nothingsounds like move semantic, aha?
-
when copying data to vector (or something like this), you need to pay more attention:
std::vector<int> v; int a[] = {1, 2, 3}; std::copy(a, a + 3, std::back_inserter(v));
std::back_inserter()
returns astd::back_insert_iterator
, which is an output iterator pointing to the end of the container andpush_back()
method of the container will be called whenever the iterator is assigned to.But if you must copy to the begin of the container, it's better to resize the container in advance to ensure that the size of container is larger than the size of data copied:
std::vector<int> v; int a[] = {1, 2, 3}; v.resize(3); std::copy(a, a + 3, v.begin());
-
note that
size()
ofstd::vector
(maybe most stl containers are also applied) return a unsigned value:std::vector<int> v; std::cout << v.size() - 1 << std::endl; // 18446744073709551615
-
constexpr
does not always have an address. for example, the following code will complainundefined reference to 'Card::NonWildColors'
. that is becauseCard::NonWildColors
doesn't have an address, which cannot be traversed in a range-based loopstruct Card { constexpr static std::initializer_list<CardColor> NonWildColors = {/*data*/}; }; for (auto color : Card::NonWildColors) { // do something }
the right way is to declare as
const static
and define somewhere else:struct Card { const static std::initializer_list<CardColor> NonWildColors; }; const std::initializer_list<CardText> Card::NonWildTexts = {/*data*/};
-
when passing a method of a class as callable, usually there are two ways:
-
using
std::bind
:class A { void f() {} void g() { some_func(std::bind(&A::f, this)); } };
-
using lambda:
class A { void f() {} void g() { some_func([this]() { return f(); }]); } };
-
-
when using asio, invocation to
io_context::run()
will block if there is still some async work to complete. reference -
to install MinGw on Windows, take this for a reference. after installation, some necessary binarys should already have been added to PATH, run
g++
to have a check. and then, we can use it likecmake -G "MinGW Makefiles" ..
-
using Python to run an executable and provide input interactively, take this for a reference.
-
use
firewall-cmd
commands to query and manipulate configuration about firewall to expose service. reference