взять адрес функции-члена, не обращаясь к классу экземпляра по конкретному имени?

Теперь, когда у нас есть ключевое слово auto, я хотел бы получить адрес члена экземпляра класса без необходимости статически ссылаться на его класс.

например (старая школа)

MyInterestingClass & foo = m_holder.GetInteresting();
foo.SetEnableNotification(false);
ScopeGuard restore_notifications = MakeObjGuard(foo, &MyInterestingClass::SetEnableNotification, true);
// do stuf...

С++ 11 с использованием авто???

auto & foo = m_holder.GetInteresting();
foo.SetEnableNotification(false);
ScopeGuard restore_notifications = MakeObjGuard(foo, &foo.SetEnableNotification, true);
// do stuf...

Однако &foo.memfun не компилируется. Каков синтаксис/канонический подход к этому? Конечно, мы не хотим ссылаться на конкретный тип foo, если можем этого избежать, поскольку в противном случае auto кажется действительно слабым соусом, не так ли?


person Mordachai    schedule 14.03.2013    source источник
comment
ты пробовал &decltype(foo)::SetEnableNotification? Я бы предположил, что это сработает   -  person Stephen Lin    schedule 14.03.2013
comment
Я думаю, что подход в настоящее время (по крайней мере, для класса, подобного охраннику области) будет просто использовать лямбда: auto restore_notifications = make_scope_guard([&]{ foo.SetEnableNotification(true); });   -  person GManNickG    schedule 14.03.2013
comment
К сожалению, это не так. &decltype(foo)::SetEnableNotifications -> error C2039: 'SetEnableNotifications' : is not a member of 'global namespace''`   -  person Mordachai    schedule 14.03.2013
comment
@Mordachai Это ошибка в Visual Studio, использование :: после decltype(...) всегда терпит неудачу. Один из обходных путей, который я видел, — это typedef decltype(...), а затем ссылаться на вложенную вещь, используя typedef.   -  person Praetorian    schedule 14.03.2013
comment
@Praetorian: Помимо этого есть неотъемлемая проблема.   -  person Xeo    schedule 14.03.2013
comment
@Xeo Да, я видел ваш комментарий к ответу ниже. Но ошибка, о которой сообщает VS, тем не менее неверна.   -  person Praetorian    schedule 14.03.2013


Ответы (1)


Это должно работать (по крайней мере, в GCC 4.7.2):

ScopeGuard restore_notifications = MakeObjGuard(foo,
    &std::remove_reference<decltype(foo)>::type::SetEnableNotification, true);

Я попробовал его в уменьшенном корпусе, и он отлично компилируется.

person Stephen Lin    schedule 14.03.2013
comment
Нет, потому что foo это MyInterestingClass&. - person Xeo; 14.03.2013
comment
Спасибо, что показали, как это можно заставить работать. Я думаю, что @GManNickG правильно использует лямбду. Приведенный выше синтаксис оставляет желать лучшего. - person Mordachai; 14.03.2013
comment
конечно, я оставлю его здесь, так как он отвечает на вопрос, на случай, если кому-то еще это понадобится. - person Stephen Lin; 14.03.2013