Double brackets?

Viewed 292

Just encountered this bit of code:

if(iElement->getData().contains("someText") and iElement->getData()("someOtherText").toString() == "true")

What is boggling my mind is this part:

iElement->getData()("someOtherText").toString()

More precisely having: ()()

I haven't seen an overloader anywhere.

This is supposed to be C++ code by the way. Compiles and runs fine.

Could not find any information anywhere since I don't know what to even search for... Can someone please explain?

2 Answers
 iElement->getData()("someOtherText").toString()

Is processed in following order

  1. Call iElement->getData()

  2. On the object returned by getData(), call operator(), i.e the overloaded call operator, with the argument "someOtherText"

  3. On the object returned by operator(), call toString()

Notice that operator() must not necessarily be overriden. getData() could e.g return a function pointer as well.

In question about ()() first pair of parentheses corresponds to the call iElement->getData() returning callable object and second pair of parentheses represents operator() to call returned callable object with string parameter and returning type String (which has member function toString() as in source code for String in the source code below).
For our case we declare:

function<String (string)> callableObject;

This callable object is called as

callableObject(“callOperator or functionPointer or someOtherText”);

Callable object could be constructed using call operator or function pointer (Sebastian Hoffmann and in the discussion) and other constructs (see source code for getDataWithCallableObject()):

         1 Function object
         1.1 Function object
               CallOperatorStruct callOperatorStruct;
               callableObject = callOperatorStruct;
         1.2 Lambda, named lambda
               String str;
               callableObject = [](string s) { return str; };
               auto namedLambda = [](string s) { return str; };
               callableObject = namedLambda;
         2 Function
         2.1 Free function
               callableObject = freeFunction;
         2.2 Free function pointer
               callableObject = &freeFunction;
         2.3 Member function
               callableObject = MemberFunctionStruct::staticMemberFunction;
         2.4 Member function pointer
               MemberFunctionStruct memberFunctionStruct;
               callableObject = bind (&MemberFunctionStruct::memberFunction, memberFunctionStruct, _1);
               callableObject = &MemberFunctionStruct::staticMemberFunction;

Source code

#include <functional>
#include <string>

using namespace std;
using namespace std::placeholders;

struct String {
  bool toString () {
    return "true";
  }
};

struct CallOperatorStruct {
  String operator()(string s) {
    return str;
  }

  String str;
};

struct Element {
  CallOperatorStruct& getData () {
    return data;
  }
  CallOperatorStruct data;

  static function<String (string)> getDataWithCallableObject ();
};

int main () {
  Element* iElement = new Element ();

  if (iElement->getData()("someOtherText").toString()){};

  if (iElement->getDataWithCallableObject()("someOtherText").toString()){};
}

String str;

struct MemberFunctionStruct {
  String memberFunction (string s) {
    return str;
  };

  static String staticMemberFunction(string s) {
    return str;
  };
};

String freeFunction (string s) {
  return str;
};

function<String (string)> Element::getDataWithCallableObject () {
  function<String (string)> callableObject;

  // 1 Function object
  // 1.1 Function object
  CallOperatorStruct callOperatorStruct;
  callableObject = callOperatorStruct;

  // 1.2 Lambda, named lambda
  callableObject = [](string s) { return str; };
  auto namedLambda = [](string s) { return str; };
  callableObject = namedLambda;

  // 2 Function
  // 2.1 Free function
  callableObject = freeFunction;

  // 2.2 Free function pointer
  callableObject = &freeFunction;

  // 2.3 Member function
  callableObject = MemberFunctionStruct::staticMemberFunction;

  // 2.4 Member function pointer
  MemberFunctionStruct memberFunctionObj;
  callableObject = bind (&MemberFunctionStruct::memberFunction, memberFunctionObj, _1);
  callableObject = &MemberFunctionStruct::staticMemberFunction;

  return callableObject;
}
Related