Имея дело с указателями функций-членов класса, мы можем вызывать функцию для экземпляра объекта со следующим синтаксисом:
struct X {
void foo();
};
X x; // Instance
auto f = &X::foo; // Member function pointer
(x.*f)(); // Call function f on x
При наличии необработанного указателя экземпляра синтаксис таков:
X *xptr = new X();
(xptr->*f)();
Это прекрасно следует аналогии со статическим вызовом функции:
x.foo();
x->foo();
Однако, когда у меня есть интеллектуальный указатель класса, это не работает:
unique_ptr<X> xsptr(new X());
(xsptr->*f)(); // g++: error: no match for 'operator->*' in 'xsptr ->* f'
Я обхожу эту проблему, сначала применяя оператор разыменования, а затем вызывая с синтаксисом .
:
((*xsptr).*f)();
Насколько это некрасиво?
Предполагается ли, что компилятор отвергает стрелочный синтаксис сверху? Потому что обычно (при статическом вызове функции) он вызывает operator ->
. Разве ->*
не должен также просто позвонить operator ->
?
Ошибка компилятора частично отвечает на этот вопрос: ошибка гласит, что мы можем перегрузить operator ->*
для вызова указателя функции-члена на разыменованный объект, чего unique_ptr
не делает. Но это вызывает больше вопросов. Почему бы умным указателям этого не делать, если этого требует язык? Предполагается ли, что не это делается, потому что это создает другие проблемы? И почему мы вообще должны писать этот оператор вместо неявного вызова указателя функции-члена на объект, возвращаемый ->
? (Поскольку это поведение при написании xsptr->foo()
)
->*
для значения, не являющегося указателем, должно что-то делать? Компилятор не знает, чтоunique_ptr
пытается имитировать необработанный указатель. Однакоoperator->*
можно перегрузить, но его чистая реализация раздражает. - person Xeo   schedule 25.03.2013->*
, а именно вызвать указатель члена на объект, возвращаемыйoperator->
, примерно так:operator ->*(memptr) { return ((*this)->).*memptr(); }
. Но поскольку он не этого не делает, почему в типах указателей в C++11 этот оператор не определен? Есть ли причина? - person leemes   schedule 25.03.2013call(xsptr, f, args);
- person Peter Wood   schedule 25.03.2013call
? Есть лиstd::call
или вы имеете в виду, что я мог бы реализовать общую функциюcall
, которая справится с этим за меня? - person leemes   schedule 25.03.2013call
самостоятельно. - person Peter Wood   schedule 25.03.2013