1

I've been coding in C/C++ for a while and I'm using the https://github.com/jarro2783/cxxopts library. The library uses the add_options() function to grab it's configuration, like this:

options.add_options() ("option1", "Description1") ("option2", "Description2");

And you can add an arbitrary number of options.

It came as a surprise that this is valid C/C++ and works; I have never seen something like that.

How are they doing it? Is there a name for this syntax?

DanyAlejandro
  • 1,440
  • 13
  • 24
  • Looked at the source yet? – Ulrich Eckhardt Jun 13 '18 at 19:26
  • 4
    Overloading the [function call operator](http://en.cppreference.com/w/cpp/language/operator_other) and chaining. – Fred Larson Jun 13 '18 at 19:27
  • This is likely done by using a type that has `operator()` which returns an instance of the same type. – François Andrieux Jun 13 '18 at 19:27
  • This is some dark magic, and I'm not sure if I should be impressed or terrified. This is like what some people do with JavaScript functions where they add functions to the functions... – tadman Jun 13 '18 at 19:35
  • @ulrich-eckhardt of course looking at the source code was the first thing I did, but there was a possibility that this was a new feature of some C++ version I didn't know about (first thing I googled). I've been doing C/C++ for 3 years on a daily basis (an a lot of industrial experience before that), no need to bash my question as me being lazy, I truly want to learn how to do this for my own code. – DanyAlejandro Jun 13 '18 at 19:36
  • 1
    Actually a variant of the [Named Parameter Idiom](https://stackoverflow.com/a/2700976/10077), it appears. – Fred Larson Jun 13 '18 at 19:38
  • 1
    You may want to program in C or C++. Switching between the two can get very annoying sometimes and besides, there is no C/C++ language. For example, in C you don't have member functions and you can't overload functions or operators. – Thomas Matthews Jun 13 '18 at 19:48
  • @thomas-matthews You're right on that, but I usually just need some behaviors from C regarding memory. I deal with enough data to easily fill my RAM (computer vision) and sometmes it's just safer for me to use pointers instead of references. I use C++ as much as I can though, C when C++ is too safe for my own speed needs. – DanyAlejandro Jun 13 '18 at 19:53
  • @DanyAlejandro, there are many lazy people here that want to be fed information that they are too lazy to locate themselves. Your question honestly seems like one, simply because you include a link to the source but no indication that you investigated there. Anyhow, good that you got answers. BTW: There's another way you could have found out how this works, you could have stepped through it with a debugger. If you don't know how to use one, you're missing one of the most important tools for a programmer. – Ulrich Eckhardt Jun 13 '18 at 19:56
  • @ulrich-eckhardt Thanks for the tip, I know how to use a debugger, and I decided to ask the developer community instead; they know things a debugger cannot teach me and the question was worth it. – DanyAlejandro Jun 13 '18 at 22:04

1 Answers1

9

options.add_options() returns an object.

That object has the function call operator overload that takes two strings, which most likely looks like

ObjectType& operator()(std::string const& option, std::string const& value);

which allows you to chain the function calls.

Here's a simple program that demonstrates the concept.

#include <iostream>

struct Foo
{
   Foo& operator()(int x)
   {
      std::cout << "Got " << x << std::endl;
      return *this;
   }
};

struct Bar
{
   Foo getFoo() { return Foo(); }
};


int main()
{
   Bar b;
   b.getFoo()(10)(200)(30);
}

Output of the program:

Got 10
Got 200
Got 30

That line in main is equivalent to:

Foo foo = b.getFoo();
foo(10);
foo(200);
foo(30);

PS

Personally, I find that style of coding a bit cryptic and best avoided. I would rather see:

auto& option = options.add_options();
option.addOption("option1", "Description1");
option.addOption("option2", "Description2");

That's a lot clearer to understand, IMO.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • Amazing, will definitely use this in the future! – DanyAlejandro Jun 13 '18 at 19:53
  • 1
    @DanyAlejandro Even though I understand the syntax, i don't encourage such coding style. – R Sahu Jun 13 '18 at 20:01
  • Yes, I recognized this style from using JSON objects to set-up function calls in JavaScript, which is very practical, and that's what made me so excited. But other C++ programmers probably don't agree, and I don't want to force people to google to read my code. – DanyAlejandro Jun 13 '18 at 20:05