Posts Tagged ‘C++’

Articles

Build Boost 1.55 on Linux

In howto on Aug 2, 2016 by theoryl Tagged: , ,

Boost is a very extensive C++ library. To compile + install:

wget http://heanet.dl.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2
tar xz boost_1_55_0.tar.bz2
cd boost_1_55_0
mkdir ../boost
./bootstrap.sh --prefix=../boost
./b2 install

Articles

Use custom class as C++ map key

In howto on Jul 5, 2016 by theoryl Tagged: ,

To be able to use a custom class as the key in C++ std::map, a less-than operator (operator<) must be defined for the custom class. One way is to define it in the class itself:

class MyClass{
public:
    MyClass(int x, int y) : _x(x), _y(y) {}
    ~MyClass() {}

    bool operator<(const MyClass& other) const{
        return (_x < other._x) || (!(other._x < _x) && (_y < other._y));
    }

private:
    int _x, _y;
};

Alternatively, one can define a comparison function (in the global scope):

class MyClass{
public:
    MyClass(int x, int y) : _x(x), _y(y) {}
    ~MyClass() {}

    double x() const { return _x; }
    double y() const { return _y; }

private:
    int _x, _y;
};

bool operator<(const MyClass& lhs, const MyClass& rhs) {
    return (lhs.x() < rhs.x()) || (!(rhs.x() < lhs.x()) && (lhs.y() < rhs.y()));
}

Or, define a comparison functor (this is probably the recommended way):

class MyClass{
public:
    MyClass(int x, int y) : _x(x), _y(y) {}
    ~MyClass() {}

    double x() const { return _x; }
    double y() const { return _y; }

private:
    int _x, _y;
};

struct MyComparator {
    // use it like std::map<MyClass, int, MyComparator>
    bool operator()(const MyClass& lhs, const MyClass& rhs) const {
        return (lhs.x() < rhs.x()) || (!(rhs.x() < lhs.x()) && (lhs.y() < rhs.y()));
    }
};

Note that std::map decides two keys are equal if (!(key1 < key2) && !(key2 < key1)).

Articles

C++ style guide

In howto on Aug 29, 2013 by theoryl Tagged: , , ,

I have always wished that my codes are more readable. So I decided to adopt a proper style guide for my codes. I decided to follow the style guide from Google and the documentation guide from Doxygen with Markdown text formatting.

My boilerplate:

/** 
 *  @file Example.h
 *  @brief This is an example code
 *  @author user <user@example.com>
 *  
 *  A looong description.
 *  A formula: \f$ \sqrt{ a^2 + b^2 } \f$
 */

#ifndef EXAMPLE_H_
#define EXAMPLE_H_

#include <vector>  //  ordered by C library, C++ library, other libraries' .h, user's .h

...

#endif  // EXAMPLE_H_

(Indent with 4 spaces, although Google recommends 2 spaces. No tabs.)

My class template:

/** 
 *  @class Test
 *  
 *  Some description.
 */
class Test {
  public:
    /** An enum type. 
     *  Some description.
     */
    enum EnumType {
        int EVal1,   ///< enum value 1
        int EVal2    ///< enum value 2
    };

    /// Default constructor
    Test();
    /// Constructor
    Test(int value)
          : value_(value);
    /// Destructor
    ~Test() {}

    void member();   ///< a member function
    
  private:
    int value_;      ///< an integer value
};

class ChildTest : public Test {
  private:
    int child_value_;
};

(Comment block must be placed in front of the class. Declare in order typedefs and enums, static consts, constructors, destructor, methods, class members.)

My function template:

/** 
 *  This function takes two arguments and returns an integer value.
 *
 *  @param a An integer argument
 *  @param b A const char* argument
 *  @return  A result
 */
int TestFunction(int a,const char *s) {
    if (condition) {  // No spaces inside parentheses
        ...
    } else {  // The else goes on the same line as the closing brace.
        ...
    }
    for (int i = 0; i < kSomeNumber; ++i) {
        ...
    }
    ...
}

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
        Type par_name1,  // 8 space indent
        Type par_name2,
        Type par_name3) {
    DoSomething();  // 4 space indent
    ...
}

(Comment block must be placed in front of the function. Input arguments are values or const references while output arguments are pointers. Prefer small and focused functions)

Some common special commands:

/**
 *  @file to document a file.
 *  @namespace to document a namespace
 *  @struct to document a C-struct.
 *  @var to document a variable or typedef or enum value.
 *  @def to document a #define.
 *  
 *  @bug bug description
 *  @todo paragraph describing what is to be done
 */

Horizontal rule

//______________________________________________________________________________

Read More »