Ответ 1
Подводя итог обсуждению в комментариях: поддержка ссылочных функций-членов в качестве аргументов шаблона является относительно новой функцией для некоторых компиляторов. Тем не менее, последние версии большинства компиляторов будут компилировать такой код.
Например:
#include <iostream>
struct MyClass
{
void Foo(int) const &
{
std::cout << "calling: void Foo(int) const &\n";
}
void Foo(int) const &&
{
std::cout << "calling: void Foo(int) const &&\n";
}
};
template<typename T>
void CallFoo_lvalue(void (T::*foo)(int) const &)
{
T temp;
(temp.*foo)(0);
}
template<typename T>
void CallFoo_rvalue(void (T::*foo)(int) const &&)
{
(T{}.*foo)(0);
}
int main()
{
CallFoo_lvalue(&MyClass::Foo);
CallFoo_rvalue(&MyClass::Foo);
}
Будет компилироваться с помощью:
- gcc (работает с 7.0.0)
- Visual С++ (работает с v19.10.24903.0)
производя следующий вывод:
calling: void Foo(int) const &
calling: void Foo(int) const &&
Для тех, кто блуждает, что &
и &&
для: здесь цитата из @JustinTime:
В принципе, и является рефлексиатором lvalue, и && является rvalue ref-qualifier (привязывается к временному объекту); в его примере MyClass m; m.Foo(3); назвал бы верхний, а MyClass {}. Foo (3); назвал бы нижний. Они действуют на неявный параметр объекта; именующий ref-qualifier связывается с ссылкой lvalue и rvalue ref-qualifier привязывается к ссылке rvalue (функции, которые не принимают параметр как lvalue reference, но пусть он привязывается к любому). Обратите внимание, что они фактически не изменяют этот тип.