Search code examples
c++boostboost-program-options

How does boost program_options work?


The weird thing to me is, that boost's options_description uses multi-line code without backslash or semicolon or comma. I did a little research, but found nothing.

(Code taken from official boost's tutorial):

int opt;
po::options_description desc("Allowed options"); 
desc.add_options()
    ("help", "produce help message")
    ("optimization"   , po::value<int>(&opt)->default_value(10), "optimization level")
    ("include-path,I ", po::value< vector<string> >()          , "include path")
    ("input-file     ", po::value< vector<string> >()          , "input file") ;

How is it implemented? Is it a macro?


Solution

  • It's a bit of a strange syntax in C++ but if you're familiar with JS (for example), you might be aware of the concept of method chaining. This is a bit like that.

    add_options() returns an object with operator() defined. The second line calls operator() on the object returned by the first line. The method returns a reference to the original object, so you can keep calling operator() many times in a row.

    Here's a simplified version of how it works:

    #include <iostream>
    
    class Example
    {
    public:
        Example & operator()(std::string arg) {
            std::cout << "added option: " << arg << "\n";
            return *this;
        }
        Example & add_options() {
            return *this;        
        }
    };
    
    int main()
    {
        Example desc;
        desc.add_options()
            ("first")
            ("second")
            ("third");
        return 0;
    }
    

    As pointed out by gbjbaanb in the comments, this is actually quite similar to how chaining of assignments a = b = c = 0 works for classes. It is also similar to the behaviour that is pretty much taken for granted when using ostream::operator<<: you expect to be able to do std::cout << "string 1" << "string 2" << "string 3".