Две круглые скобки после переменной?



У меня есть нечто подобное в одном методе



    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 является переменной, мне интересно, что означают две скобки после переменной. Может быть, я что-то неправильно понял?

666   3  

3 ответов:

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)); 

Это похоже на OpenFOAM, который имеет свою собственную реализацию хэш-таблицы.

Если вы посмотрите в src / OpenFoam / containers/HashTable/HashTable / HashTable.H, строка 454 (по крайней мере в моей копии), вы обнаружите, что iterator перегружает operator() и operator*, чтобы вернуть ссылку на текущее значение итератора.

Чтобы немного прояснить, C++ позволяет перегружать многие операторов, которые вы используете для обеспечения специфичной для домена функциональности. Это позволяет, скажем, vector.add(otherVector) Использовать "очевидный" синтаксический сахар vector + otherVector вместо этого. Недостатком является то, что то, что очевидно, не всегда так очевидно, как показывает этот вопрос.

Эта конструкция

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

Означает, что сначала временный объект типа cstrIter создается с помощью конструктора по умолчанию

cstrIter()

И после этого для этого объекта используется оператор вызова функции

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

Чтобы было понятнее, можно переписать выражение следующим образом

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

Comments

    Ничего не найдено.