Две круглые скобки после переменной?
У меня есть нечто подобное в одном методе
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 ответов:
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