为什么在此上下文中无法推导出模板参数?

Joh*_*ohn 16 c++ templates member-function-pointers c++11 ref-qualifier

任何人都可以解释为什么编译器(g ++,visual c ++)在这种情况下无法推断模板参数?

struct MyClass
{
    void Foo(int x)&  {}
    void Foo(int x)&& {}
};

template<typename T>
void CallFoo(void(T::*func)(int)&)
{
    //create instance and call func
}

int main()
{
   CallFoo(&MyClass::Foo); // Fails to deduce T
}
Run Code Online (Sandbox Code Playgroud)

为什么编译器不能将T推导为MyClass?这仅适用于ref限定符重载的方法.如果方法被const-ness或参数类型重载,一切正常.在这种情况下,似乎只有Clang才能推断T.

AMA*_*AMA 1

Summarizing discussion in the comments: the support for reference-qualified member functions as template arguments is a relatively new feature for some compilers. However, the latest versions of most compilers will compile such code.


For example:

#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);
}
Run Code Online (Sandbox Code Playgroud)

Will compile with:

producing the following output:

calling: void Foo(int) const &
calling: void Foo(int) const &&
Run Code Online (Sandbox Code Playgroud)

For those who are wondering what & and && are for: here's the quote from @JustinTime:

基本上, & 是左值引用限定符, && 是右值引用限定符(绑定到临时对象);在他的例子中,MyClass m;m.Foo(3); 会调用最上面的一个,而 MyClass{}.Foo(3); 会调用底部的一个。它们作用于隐式对象参数;左值引用限定符绑定到左值引用,右值引用限定符绑定到右值引用(既不将参数作为左值引用,又让它绑定到其中一个的函数)。请注意,它们实际上并没有改变 *this 的类型。