Tag Archives: C++

Erasing from a vector by index

Use the vector::erase function to erase an element, or range of elements from a vector. It returns an iterator pointing to the element after the last one erased:

v.erase(v.begin() + pos);
v.erase(v.begin() + start, v.begin() + end);

For example, this program populates a vector with the numbers 0 to 9 and then erases 8, before erasing 3 to 5:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    typedef std::vector<int> intvec;
    intvec v(10);
    std::iota(v.begin(), v.end(), 0);
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\n";

    std::cout << "erase 8:\n";
    intvec::const_iterator it = v.erase(v.begin() + 8);
    std::cout << "next element is " << *it << "\n";
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\n";

    std::cout << "erase 3 to 5:\n";
    it = v.erase(v.begin() + 3, v.begin() + 6);
    std::cout << "next element is " << *it << "\n";
    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
    std::cout << "\n";
}

You can make a generic function to erase from a container by index by using std::advance to move to the first (and optionally last) element to remove and then calling the container’s own erase method:

template <class Container>
typename Container::iterator erase(Container& cont, size_t pos, size_t len = 1)
{
    typename Container::iterator it1 = cont.begin();
    std::advance(it1, pos);
    typename Container::iterator it2 = it1;
    std::advance(it2, len);
    return cont.erase(it1, it2);
}

Use it like this:

erase(vec, 8);    // erase 8
erase(vec, 3, 3); // erase 3 to 5

Note that this will be O(n) for lists because their iterators are not RandomAccessIterators.

Related

Lifetime of local static variables

Local static variables are constructed when the program flow first encounters their constructor call. This means that if control does not reach it, they will not be constructed.
They are destroyed at the end of the program. As with all objects, local statics are destroyed in reverse order of their creation.

#include <iostream>
#include <string>

struct Announcer {
    Announcer(const std::string& str) 
        : msg(str)
    {
        std::cout << "Created " << msg << "\n";
    }
    ~Announcer() 
    { 
        std::cout << "Destroyed " << msg << "\n";
    }
    std::string msg;
};

void func(bool condition) 
{
    if (condition) {
        static Announcer a1("in condition");
    }
    static Announcer a2("in func");
}

int main(int argc, char *argv[])
{
    func(argc > 1);
}

Running this without an argument produces:

Created in func
Destroyed in func

Because the code never enters the conditional in func(), a1 is never created.
Running it with an argument produces:

Created in condition
Created in func
Destroyed in func
Destroyed in condition

Here, the conditional has been entered, so a1 is created. Note the order of the destructor calls – in revese order to the order of construction.

How to create, launch, and join a thread in C++

Contents

  • Method 1: Boost.Thread
  • Method 2: pthreads (POSIX)
  • Method 3: Windows threads
  • Method 4: std::thread (C++11)

Method 1: Boost.Thread

#include <iostream>
#include <string>
#include <boost/thread.hpp>

class Hello
{
public:
	void operator()(const std::string& msg) const
	{
		std::cout << msg << "\n";
	}
};

int main()
{
	boost::thread t = boost::thread(Hello(), "Hello");
	t.join();
}

Method 2: pthreads (POSIX)

#include <iostream>

#include <pthread.h>

void* hello(void *msg)
{
    std::cout << static_cast<const char*>(msg) << "\n";
    return NULL;
}

int main()
{
    pthread_t thread;
    pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    char msg[] = "Hello";
	int status = pthread_create(&thread, &attr, hello, msg);
	pthread_attr_destroy(&attr);
	if (status != 0) {
        std::cerr << "Failed to create thread\n";
        return 1;
	}
    status = pthread_join(thread, NULL);
    if (status != 0) {
        std::cerr << "Failed to join thread\n";
        return 1;
    }
}

Method 3: Windows threads

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <Windows.h>
#include <process.h>

#include <iostream>

void hello(void *msg)
{
	std::cout << static_cast<const char*>(msg) << "\n";
}

int main()
{
	char msg[] = "Hello";
	HANDLE thread = reinterpret_cast<HANDLE>(_beginthread(hello, 0, msg));
	if (thread == INVALID_HANDLE_VALUE) {
		std::cerr << "Failed to create thread\n";
		return 1;
	}
	WaitForSingleObject(thread, INFINITE);
}

Method 4: std::thread (C++11)

#include <string>
#include <iostream>
#include <thread>

void hello(const std::string& msg)
{
    std::cout << msg << "\n";
}

int main()
{
    std::thread t(hello, "Hello");
    t.join();
}

Setting up Facebook Folly on Ubuntu

This is how I installed the Facebook Folly C++ libraries on Ubuntu.

Step 1: The source

I downloaded master.zip from https://github.com/facebook/folly/archive/master.zip and unzipped it, creating the directory /home/martin/folly-master.

Step 2: Install prerequisites

I just installed everything mentioned in the README.md. I had most of these already:

sudo apt-get install \
    g++ \
    automake \
    autoconf \
    autoconf-archive \
    libtool \
    libboost-all-dev \
    libevent-dev \
    libdouble-conversion-dev \
    libgoogle-glog-dev \
    libgflags-dev \
    liblz4-dev \
    liblzma-dev \
    libsnappy-dev \
    make \
    zlib1g-dev \
    binutils-dev \
    libjemalloc-dev \
    libssl-dev
    libunwind8-dev \
    libelf-dev \
    libdwarf-dev
    libiberty-dev

Step 3: Build

autoreconf -ivf
./configure
make
sudo make install

I couldn’t get make check to work because Google Test has changed, so I skipped that step.

Step 4: Install header files

sudo mkdir /usr/include/folly
sudo mkdir /usr/include/folly/detail
sudo cp /home/martin/folly-master/folly/*.h /usr/include/folly
sudo cp /home/martin/folly-master/folly/detail/*.h /usr/include/folly/detail
sudo cp -r /home/martin/folly-master/folly/compatibility /usr/include/folly

I’m not sure if copying the header files from detail was necessary, but it doesn’t do any harm.

Step 5: Install the libraries

sudo cp /home/martin/folly-master/folly/.libs/libfolly.so.57.0.0 /usr/local/lib
cd /usr/local/lib
sudo ln -s libfolly.so.57.0.0 libfolly.so
sudo ln -s libfolly.so.57.0.0 libfolly.so.57
sudo ldconfig -v

Step 6: Try it

I wrote this program in hello.cpp:

#include <iostream>
#include <folly/FBString.h>

int main()
{
    folly::fbstring str("Hello, Folly World!");
    std::cout << str << "\n";
}

I compiled it like this:

g++ hello.cpp -o hello -lfolly

Finally, I ran it:

./hello
Hello, Folly World!

Success!

How to do string formatting in C++

Contents

  1. Use vsnprintf() (C++11 and POSIX)
  2. Use Boost.Format
  3. Use folly::format()

Method 1: Use vsnprintf() (C++11 and POSIX)

#include <iostream>
#include <vector>
#include <string>
#include <cstdarg>
#include <cstring>

std::string format(const std::string& format, ...)
{
    va_list args;
    va_start (args, format);
    size_t len = std::vsnprintf(NULL, 0, format.c_str(), args);
    va_end (args);
    std::vector<char> vec(len + 1);
    va_start (args, format);
    std::vsnprintf(&vec[0], len + 1, format.c_str(), args);
    va_end (args);
    return &vec[0];
}

int main()
{
    char str[] = "%s => %d";
    std::cout << string_format(str, "apples", 7) << "\n";
}

Method 2: Use Boost.Format

#include <iostream>
#include <boost/format.hpp>

int main()
{
    char str[] = "%s => %d";
    std::cout <<  boost::str(boost::format(str) % "apples" % 7) << "\n";
}

Reference: Boost Format library

Method 3: Use folly::format()

#include <iostream>
#include <folly/Format.h>

int main()
{
    char str[] = "{} => {}";
    std::cout <<  folly::format(str, "apples", 7) << "\n";
}

Reference: folly/Format.h

Related

Calling a base class virtual function from a derived class

You can call a base class version of a virtual function from a derived class by prefixing its name with the name of the base class. For example, if you have the following base class:

class Base
{
    public:
        virtual void method()
        {
            std::cout << "Base::method()" << "\n";
        }
        virtual ~Base()
        {
        }
};

You can call its version of method() within a derived class like this:

class Derived : public Base
{
    virtual void method()
    {
        Base::method();
        std::cout << "Derived::method()" << "\n";
    }
    virtual ~Derived()
    {
    }
};

Example program:

int main()
{
    Base *d = new Derived();
    d->method();
    delete d;
}
Base::method()
Derived::method()

Note that if the base class has inherited its version of a method, rather than implementing it, you will get the inherited version. So for example in the classes below, Parent inherits method() from Grandparent, and does not override it. If Child call’s Parent‘s version of method, the inherited one from Grandparent is called:

class Grandparent
{
    public:
        virtual void method()
        {
            std::cout << "Grandparent::method()" << "\n";
        }
        virtual ~Grandparent()
        {
        }
};

class Parent : public Grandparent
{
    public:
        virtual ~Parent()
        {
        }
};

class Child : public Parent
{
    virtual void method()
    {
        Parent::method();
        std::cout << "Child::method()" << "\n";
    }
    virtual ~Child()
    {
    }
};

Example program:

int main()
{
    Parent *p = new Child();
    p->method();
    delete p;
}
Grandparent::method()
Child::method()

See also: Calling the Base Class Constructor for how to call the base class constructor from a derived class, and Virtual Base Classes for how to call a base class method to disambiguate multiple inheritance.
See Typedef super for a handy idiom for referring to the base class.

Where to put default parameters in C++

You should put default parameters in the header file, where clients can see them, as this makes them self-documenting.

Additionally, if you conceal default parameters from clients, it makes it impossible for them to take a pointer to the function.
This includes using std::ptr_fun, std::mem_fun and std::mem_fun_ref.

The only exception if for private functions that clients never use, since there may be a benefit in being free to change them without clients needing to recompile.

std::move()

The std::move() operator is a cast that gets an xvalue reference to an object, allowing it to be moved. Moving the object instead of copying it increases efficiency.

For example, consider the following swap() function:

template <typename T>
void swap(T& a, T& b)
{
    T tmp(a);
    a = b;
    b = tmp;
}

When this runs, a is first copied to tmp, then b is copied to a, and finally tmp is copied to b. If a and b were expensive objects to copy, this would be very inefficient.

With move(), we can rewrite the swap() function this way:

#include <utility>
template <typename T>
void swap(T& a, T& b)
{
    T tmp(std::move(a));
    a = std::move(b);   
    b = std::move(tmp);
}

Now if a and b are of a class that has a move constructor and assignment operator, they will be efficiently moved rather than copied.

Finding the size of arrays and containers

Arrays

You can find the size of an array with the following template function:

template <typename T, size_t N>
size_t size(T (&)[N])
{
    return N;
}

Example:

#include <iostream>

int main()
{
    int ints[] = {1, 2, 3, 4};
    const char *pchars[] = {"a", "b", "c", "d"};
 
    std::cout << size(ints) << "\n";
    std::cout << size(pchars) << "\n";
}
4
4

Note that once an array has decayed to a pointer by being passed to a function, this will not work.

Containers

You can extend this to containers with the following two functions, which take template template parameters:

template <template<class, class> class Container, class T, class Allocator>
size_t size(const Container<T, Allocator>& cont)
{
    return cont.size();
}

template <template<class, class, class, class> class Container, class Key, class T, class Compare,
        class Allocator>
size_t size(const Container<Key, T, Compare, Allocator>& cont)
{
    return cont.size();
}

Example:

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

int main()
{
    std::vector<int> vec(10);
    std::iota(vec.begin(), vec.end(), 0);
    std::map<std::string, int> dict;
    dict["apples"] = 7;
    dict["pears"] = 9;

    std::cout << size(vec) << "\n";
    std::cout << size(dict) << "\n";
}
10
2

C++11

In C++11, you can use decltype to select the container overload, so the two template template functions can be replaced with this:

template <class Container> 
auto size(const Container& cont) -> decltype(cont.size())
{
    return cont.size();
}

C++17

C++17 has added the std::size() function, which probably uses the size_t overload for arrays, and the one using decltype for containers.

How to sleep for milliseconds in C++

  1. Use usleep (POSIX)
  2. Use Sleep (Windows)
  3. Use Boost.Thread
  4. Use std::this_thread::sleep_for (C++11)

Method 1: Use usleep (POSIX)

#include <unistd.h>

int main()
{
    usleep(500);
}

Method 2: Use Sleep (Windows)

#include <Windows.h>

int main()
{
    Sleep(500);
}

Method 3: Use Boost.Thread

#include <boost/thread/thread.hpp>
int main()
{
    boost::this_thread::sleep(boost::posix_time::milliseconds(500));
}

Method 4: Use std::this_thread::sleep_for (C++11)

#include <chrono>
#include <thread>

int main()
{
    std::this_thread::sleep_for(std::chrono::milliseconds(500));
}