C++

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...
Managed Wrappers and Hidden Interdependencies
C++ c++ managed c++
Published: 2007-01-10
Managed Wrappers and Hidden Interdependencies

Let’s say you have the following unmanaged 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
#pragma unmanaged

class Stream { ... }; // Conceptual stream class

class StreamWriter
{
public:
    StreamWriter(Stream* pStream) : m_pStream(pStream) {}
    ~StreamWriter() { /* Use m_pStream in some way */ }

    ...

private:
    Stream* m_pStream;
};

void f()
{
    Stream stream;
    StreamWriter streamWriter(&stream);

    // Use streamWriter
    // streamWriter is destroyed
    // stream is destroyed
}

Note that StreamWriter’s destructor uses m_pStream (perhaps by flushing the stream). This means that the order of destruction is important — StreamWriter must be destroyed before its underlying Stream is.

Read more...
C++ Exception Handling
C++ c++
Published: 2006-01-30
C++ Exception Handling

Quick quiz: What is the behavior of the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdio.h>

int main(int argc, char* argv[])
{
    try
    {
        *((char*) 0) = 1;
    }
    catch (...)
    {
        printf("Caught exception.\n");
    }

    return 0;
}

Surprisingly, it depends! As I would expect, on many operating system / compiler combinations (such as gcc version 3.4.4 20050721 (Red Hat 3.4.4-2) as tested by Keith Garner), the dereference of the null pointer leads to a segmentation fault. However, both Microsoft Visual Studio 6.0 and Visual Studio .NET 2003 print the message Caught exception. and exit gracefully. Strange!

Read more...
Implementing IXmlWriter Part 14: Supporting Writing To A Stream
Implementing IXmlWriter c++ ixmlwriter xml
Published: 2006-01-10
Implementing IXmlWriter Part 14: Supporting Writing To A Stream

This is part 14/14 of my Implementing IXmlWriter post series.

Today I will add support for writing the generated XML to a C++ stream to last time’s IXmlWriter.

Finally the reason why I’ve insisted on calling this series IXmlWriter (instead of StringXmlWriter) should become clear: I’ve been planning on supporting writing the generated XML to more than just a string. Specifically, today I will add the ability to write the XML to a C++ ostream object, a base class in the C++ iostream library which defines a writable stream.

Read more...
Implementing IXmlWriter Part 13: Putting IXmlWriter Behind A Pimpl Firewall
Implementing IXmlWriter c++ ixmlwriter pimpl xml
Published: 2005-12-15
Implementing IXmlWriter Part 13: Putting IXmlWriter Behind A Pimpl Firewall

This is part 13/14 of my Implementing IXmlWriter post series.

As the private members of IXmlWriter are getting too numerous and too likely to change by my judgment, today I will put last time’s IXmlWriter behind a compilation firewall (pimpl).

The idea behind the pimpl idiom is to hide as much of the class definition as possible in order to avoid requiring users of the class to recompile if the class’s private members are changed. It is accomplished by moving all private members (functions, data, etc.) into a separate class (called the implementation or pimpl class) hidden from the class definition, and replacing these members with an opaque pointer to a forward declaration of this class. It works because a C++ compiler does not need to have the full definition of a class visible in order to allocate space for a pointer to the class; every pointer is a constant, fixed size (often 4 bytes).

Read more...
Implementing IXmlWriter Part 12: Supporting Pretty-Printing
Implementing IXmlWriter c++ ixmlwriter xml
Published: 2005-12-13
Implementing IXmlWriter Part 12: Supporting Pretty-Printing

This is part 12/14 of my Implementing IXmlWriter post series.

Today I will add support for pretty-printing to last time’s IXmlWriter.

Pretty-printing is the addition of whitespace at predetermined locations to make the resulting XML easier to read than when it is all on one line. In the .NET Framework’s System.Xml.XmlTextWriter class, it is supported by the properties Formatting, which allows you to enable or disable pretty-printing; Indentation, which allows you to specify how many whitespace characters indentation should use; and IndentChar, which allows you to specify the whitespace character to use for indentation. For IXmlWriter, I instead chose to expose these features exclusively through the constructor. This frees me from the worry of a user trying to change these properties after IXmlWriter has already begun writing XML, which could produce awkward results. Default parameters are used to make the use of pretty-printing optional and straightforward.

Read more...
Implementing IXmlWriter Part 11: Supporting Namespaces
Implementing IXmlWriter c++ ixmlwriter xml
Published: 2005-12-07
Implementing IXmlWriter Part 11: Supporting Namespaces

This is part 11/14 of my Implementing IXmlWriter post series.

Today I will add support for namespaces to last time’s IXmlWriter.

Namespaces are defined by the W3C recommendation Namespaces in XML. Using namespaces requires two parts: a namespace declaration, which associates a prefix with a namespace name (a user-defined, ideally globally-unique string which defines the namespace, often in the form of a URL); and the assignment of XML elements and attributes to this namespace by using the aforementioned prefix.

Read more...
Implementing IXmlWriter Part 10: Supporting WriteComment()
Implementing IXmlWriter c++ ixmlwriter xml
Published: 2005-12-02
Implementing IXmlWriter Part 10: Supporting WriteComment()

This is part 10/14 of my Implementing IXmlWriter post series.

Today I will add support for the function WriteComment() to last time’s IXmlWriter.

Quoting from Section 2.5: Comments of the XML 1.0 spec:

Comments MAY appear anywhere in a document outside other markup; in addition, they MAY appear within the document type declaration at places allowed by the grammar.

Considering this, we should allow writing comments in virtually every WriteState that the IXmlWriter can be in. In fact, some quick thought confirms that we should allow it for every WriteState but WriteState_Attribute, as a comment cannot be legally represented between the quotation marks which delimit an attribute value. With this in mind, here’s the test case I wrote:

Read more...