Недавно я обнаружил, что shared_ptr
не имеет указателя на оператор-член ->*
. Я создал простой пример:О shared_ptr и указателе на оператор-член `-> *` и `std :: bind`
template <typename Pointer, typename Function, typename... Args>
auto invoke1(Pointer p, Function f, Args... args) -> decltype((p->*f)(args...))
{
return (p->*f)(args...);
}
struct A {
void g() { std::cout << "A::g()\n"; }
};
int main() {
A a;
invoke1(&a, &A::g); // works!!
std::shared_ptr<A> sa = std::make_shared<A>();
invoke1(sa, &A::g); // compile error!!
}
Q1: Почему это так? Почему у shared_ptr нет этого оператора?
Я добавил такой оператор для shared_ptr
и пример начал работать:
template <typename T, typename Result>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)()) ->decltype(std::bind(function, pointer))
{
return std::bind(function, pointer);
}
template <typename T, typename Result, typename Arg1>
auto operator ->* (std::shared_ptr<T> pointer, Result (T::*function)(Arg1 arg1)) ->decltype(std::bind(function, pointer, std::placeholders::_1))
{
return std::bind(function, pointer, std::placeholders::_1);
}
Q2: Является ли это право реализации этого оператора? Существуют ли какие-либо «золотые» правила, как реализовать такой оператор, возможно, либо я заново изобрел колесо, либо пошел в совершенно неправильном направлении, как вы думаете? Есть ли способ, чтобы иметь одну функцию реализации этого оператора, а не как многие функции, как есть заполнители в станд ...
После этого я пришел к выводу, что std::bind
можно использовать в моем invoke
методе.
template <typename Pointer, typename Function, typename... Args>
auto invoke2(Pointer p, Function f, Args... args)
-> decltype(std::bind(f, p, args...)())
{
return std::bind(f, p, args...)();
}
Таким образом, мой пример также работает без необходимости добавления operator ->*
к shared_ptr
.
Q3: То есть, std::bind
теперь рассматривается как замена для operator->*
?
Вы пробовали: invoke1 (sa.get(), &A::g); – Alexis
@Alexis - да, я пробовал и, конечно же, это работает, но я рассматривал это обходное решение как не важное для моего вопроса. – PiotrNycz
Я даже не знал, что вы можете перегрузить этого оператора. – Mehrdad