Stl

STL Objects and Win32 Module Boundaries
C++ c++ stl win32
Published: 2008-01-04
STL Objects and Win32 Module Boundaries

Let’s say you have the following function:

1
2
3
4
void AppendChar(std::string& s, char ch)
{
    s += ch;
}

What happens if this function is exported as an ordinal function from a DLL (not an inlined piece of code inside a header) and you call it from an EXE?

It works most of the time. When it doesn’t, it corrupts your heap and causes a spectacular mess.

Read more...
Converting C++ Member Functions into Function Objects
C++ c++ stl
Published: 2007-08-28
Converting C++ Member Functions into Function Objects

Let’s say you have a C++ function that takes a function object as a parameter and calls it:

1
2
3
4
5
template <typename _Fn>
void call_functor(_Fn fn)
{
    fn();
}

Now let’s say you want to pass a class’s member function to call_functor() above, as in:

1
2
3
4
5
6
7
class C
{
    void foo() { std::cout << "foo()\n"; }
};

C c;
call_functor(/\* What do I put here? c.foo and &C::foo don't work \*/);

The STL has a pointer-to-member function adapter called std::mem_fun() which almost gets us there. Unfortunately, it doesn’t quite meet our needs because it requires us to pass a pointer to an instance of C, as in:

Read more...
STL Map Use
C++ c++ stl
Published: 2007-01-25
STL Map Use

What’s wrong with the following code?

 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
31
32
template<typename T1, typename T2>
struct my_pair
{
    typedef T1 first_type;
    typedef T2 second_type;

    my_pair() : first(T1()), second(T2()) {}
    my_pair(const T1& v1, const T2& v2) : first(v1), second(v2) {}

    T1 first;
    T2 second;
};

template<typename T1, typename T2>
inline bool operator<
    (
    const my_pair<T1, T2>& x,
    const my_pair<T1, T2>& y
    )
{
    return (x.first < y.first || x.second < y.second);
}

void f()
{
    typedef my_pair<..., ...> key_type;
    typedef ... value_type;
    typedef std::map<key_type, value_type> map_type;

    map_type map;
    // Use map
}

Answer: my_pair cannot be used as a key for a STL map because the operator< violates the rule of strict weak ordering. More specifically, the operator is not antisymmetric. Consider the following:

Read more...
STL Vector Use
C++ c++ stl
Published: 2007-01-23
STL Vector Use

I recently wrote a piece of code that looked something like the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
static const int NUM_TOTAL_VALUES = ...;
typedef ... T;

// Create vec and reserve NUM_TOTAL_VALUES spaces for later insertion
std::vector<T> vec(NUM_TOTAL_VALUES);

// Insert values into vec
for (int i = 0; i != NUM_TOTAL_VALUES; ++i)
    vec.push_back(...);

// vec should now have NUM_TOTAL_VALUES values in it (but doesn't!)

What’s wrong with this code?

Read more...
Write Functions Which Take Iterators, Not Collections
C++ c++ stl
Published: 2005-09-05
Write Functions Which Take Iterators, Not Collections

If my experience is typical, this is a very common construct:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
ReturnType Function
    (
    const std::vector<T>& container
    )
{
    typedef std::vector<T>::const_iterator iterator_t;
    for (iterator_t iter = container.begin();
         iter != container.end();
         ++iter)
    {
        // Work with *iter
    }
}

The problem with this construct is that you have forced a container choice upon the user of your function. Slightly better, and basically your only choice when interoping with C, is this:

Read more...
Prefer Iteration To Indexing
C++ c++ stl
Published: 2005-09-02
Prefer Iteration To Indexing

I’ve seen the following STL construct countless times:

1
2
3
4
std::vector<T> container;
for (int i = 0; i < container.size(); ++i) {
    // Work with container[i]
}

Unless otherwise necessary, it is better to use an STL iterator because it enables you to more easily change the underlying container. You can isolate the code changes required to one line by using typedef, as in:

Read more...