变量后的两个括号?

时间:2013-11-12 20:09:30

标签: c++ constructor parentheses

我在一种方法中有类似的东西

    autoPtr<LESModel> LESModel::New   
 95 (
 96  const volVectorField& U,
 97  const surfaceScalarField& phi,
 98  transportModel& transport,
 99  const word& turbulenceModelName
100 )
101 {
     ...
122  dictionaryConstructorTable::iterator cstrIter =                       
123  dictionaryConstructorTablePtr_->find(modelType);
     ...
143  return autoPtr<LESModel>      
144  (
145  cstrIter()(U, phi, transport, turbulenceModelName)
146  ); 
147  }

如果我是对的cstrIter是类dictionaryConstructorTable::iterator的变量(虽然找不到这个类)并从第143行开始,调用构造函数autoPtr<LesModel>并返回结果。因此,构造函数autoPtr<LESModel>之后的括号应该是参数,因为cstrIter是一个变量,我想知道变量之后的两个括号是什么意思。也许我误读了什么?

3 个答案:

答案 0 :(得分:7)

C ++支持“运算符重载”,这意味着您可以定义支持a + b等语法的类型。这可以通过定义名称为operator+的函数来实现。当一个可重载的运算符与用户定义的类型一起使用时,C ++会查找具有这些特殊名称的函数,如果找到合适的函数,则将该运算符视为函数的函数调用。

一个可以重载的运算符是函数调用运算符。当您使用对象名称时,将调用名为operator()的成员函数,就好像它是一个函数一样:

struct S {
  void operator() (void) {
    std::cout << "Hello, World!\n";
  }
};

int main() {
  S s;
  s(); // prints "Hello, World!\n"
}

看起来dictionaryConstructorTable::iterator重载函数调用操作符并返回一些类型,它也会重载函数调用操作符(或者只是使用内置操作符)。

用正常的成员函数替换函数调用操作符的使用可能会使发生的事情变得更清楚:

return autoPtr<LESModel>( cstrIter.foo().bar(U, phi, transport, turbulenceModelName)); 

答案 1 :(得分:2)

这看起来像OpenFOAM,它有自己的哈希表实现。

如果你查看src / OpenFoam / containers / HashTable / HashTable / HashTable.H,第454行(至少在我的副本中),你会发现iterator重载operator()和{{ 1}}返回对迭代器当前引用值的引用。

为了澄清一点,C ++允许您重载用于提供特定于域的功能的运算符many。例如,这允许operator*使用vector.add(otherVector)的“明显”的句法糖。不利的一面是,显而易见的并不总是那么明显,正如这个问题所表明的那样。

答案 2 :(得分:1)

这种结构

cstrIter()(U, phi, transport, turbulenceModelName)

表示首先使用默认构造函数

创建cstrIter类型的临时对象
cstrIter()

之后,函数调用运算符用于此对象

cstrIter()(U, phi, transport, turbulenceModelName)

更清楚的是你可以用以下方式重写表达式

cstrIter obj;
obj(U, phi, transport, turbulenceModelName);