简体   繁体   English

成员函数的模板推导

[英]template deduction of member functions

I'm trying to understand template argument deduction with regular functions, pointer to regular functions, member functions and pointer to member functions.我试图通过常规函数、指向常规函数的指针、成员函数和指向成员函数的指针来理解模板参数推导。 Can someone explain why the last line yields a compile error while there is no issue with standalone?有人可以解释为什么最后一行会产生编译错误而独立没有问题吗?

#include <iostream>
#include <type_traits>
 
struct A {
    int fun(float, char) const&;
};
 
void standalone(int, char) {}

template <typename T>
void what(T &&) {
    std::cout << __PRETTY_FUNCTION__ << "\n";
}
 
int main() 
{
    what(standalone); // void what(T&&) [with T = void (&)(int, char)]
    what(decltype(&standalone){}); // void what(T&&) [with T = void (*)(int, char)]
    what(decltype(&A::fun){}); // void what(T&&) [with T = int (A::*)(float, char) const &]
    what(A::fun); // main.cpp: In function 'int main()':
                  // main.cpp:30:13: error: invalid use of non-static member function 'int A::fun(float, char) const &'
      |           // what(A::fun);
      |             ^~~
}

The problem is that we cannot pass a reference to a member because from Pointers to members :问题是我们不能将引用传递给成员,因为从指针到成员

The type “pointer to member” is distinct from the type “pointer”, that is, a pointer to member is declared only by the pointer to member declarator syntax, and never by the pointer declarator syntax. “指向成员的指针”类型与“指针”类型不同,即指向成员的指针仅由指向成员声明符语法声明,从不由指针声明符语法声明。 There is no “reference-to-member” type in C++ . C++ 中没有“reference-to-member”类型

This means that we must explicitly use the address of operator in the call expression to pass a pointer to member instead(since reference to member is not allowed), as shown below:这意味着我们必须在调用表达式中显式使用运算符的地址来传递一个指向成员的指针(因为不允许引用成员),如下所示:

//-------v---------> must explicitly use address of operator
    what(&A::fun); 

Side note边注

Although irrelevant in your case, note that unlike ordinary function pointers, there is no automatic conversion between a member function and a pointer to that member.尽管与您的情况无关,但请注意,与普通的 function 指针不同,成员 function 与指向该成员的指针之间没有自动转换 That is, in case of member functions and in contexts where a pointer is expected(allowed) the expressions A::fun and &A::fun are not equivalent .也就是说,对于成员函数和需要(允许)指针的上下文,表达式A::fun&A::fun不等价的。

For a standalone function, a pointer to function can be converted contextually to function reference, eg in order to be called.对于独立的 function,指向 function 的指针可以根据上下文转换为 function 引用,例如为了被调用。 A function can be converted to a pointer to itself. function 可以转换为指向自身的指针。 In result those two lines are both legal and equal.结果这两条线既合法又相等。

what(standalone); 
what(*********************************************standalone); // stars!

For every star its argument is a reference and is contextually converted to a pointer, the result would be a reference, and so on.对于每颗星,它的参数都是一个引用,并根据上下文转换为一个指针,结果将是一个引用,等等。 In C++ a function (reference) is a type.在 C++ 中,function(参考)是一种类型。

The expression &standalone is explicitly a pointer, so what(&standalone);表达式&standalone明确地是一个指针,所以what(&standalone); would be using a pointer.将使用指针。

Now a pointer to member is a type distinct from a usual pointer and has no analog in form of reference.现在,指向成员的指针是一种不同于普通指针的类型,并且没有类似的引用形式。 The only legal way to obtain a pointer to member function or member variable is to combine unary operator& with its nested name.获取指向成员 function 或成员变量的指针的唯一合法方法是将一元运算operator&与其嵌套名称组合。

Non-static member functions are very different from free functions.非静态成员函数与自由函数有很大不同。 They can only be used in a very limited number of ways.它们只能以非常有限的方式使用。

The only possible uses for a non-static member function are in a member access expression to call the function or as an operand to & to form a pointer-to-member.非静态成员 function 的唯一可能用途是在成员访问表达式中调用 function 或作为&的操作数以形成指向成员的指针。

A::fun by itself isn't even syntactically correct in an expression if it is not preceded by & or a member access operator. A::fun前面没有&或成员访问运算符,它本身在表达式中甚至在语法上都不正确。 decltype(A::fun) is also ill-formed. decltype(A::fun)也是病式的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM