在C++中定义带有函数参数的结构体方法

Ash*_*nxy 2 c++ struct function-pointers

查看 C++ 接口代码。我无权访问实施。我做了一个小例子来展示这种行为。

struct MessageInfo{
    
    MessageInfo() : length{}, from{}, to{} {}
    
    MessageInfo(int _length, string _from, string _to) : length{_length}, from{_from}, to{_to} 
    {}

    int length;
    string from;
    string to;
      
    using IsEnumerableTag = void;
    template<typename F>
    void enumerate(F& fun) {
        fun(this->length);
        fun(this->from);
        fun(this->to);
     }
};
Run Code Online (Sandbox Code Playgroud)

有人可以向我解释一下这个结构定义中枚举结构函数成员的用法吗?

根据我的理解,该结构中的枚举可以采用函数类型作为输入参数(函数指针?)

  1. 这是否意味着每当我们创建 MessageInfo 结构体的对象时,我们都可以像下面这样调用这个方法?
  2. 如何定义函数类型,换句话说,我应该使用什么来代替“???” 在下面的代码中?
  3. 这种编码模型(更具体地说是枚举方法)有什么优点?
MessageInfo messageInfo (1000, "A", "B");
    
messageInfo.enumerate<???>(printFrom(messageInfo.From);
      
void printFrom(string f) {
     cout<<"the msgInfo is sent from "<<  f<<endl;
}
Run Code Online (Sandbox Code Playgroud)

use*_*522 5

它期望您传递一个通用的可调用函数,例如 lambda。您不必指定模板参数。可以从函数参数推导出来。

例如:

MessageInfo messageInfo (1000, "A", "B");

auto printFields = [](auto&& f){ std::cout << "Value of this field is " << f << ".\n"; };

messageInfo.enumerate(printFields);
Run Code Online (Sandbox Code Playgroud)

应该打印哪个

Value of this field is 1000.
Value of this field is A.
Value of this field is B.
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,enumerate可以用于对每个成员应用相同的操作,而不必为每个成员重复操作。

签名有点不寻常。您通常会期望FF&&代替F&. 使用 或者FF&&您可以将 lambda 表达式直接放入调用中,而不必先将其存储在变量中。

  • @Ashkanxy 出于同样的原因,您不能使用“f(1)”调用函数“void f(int&amp; x)”。非 const 左值引用 (x) 无法绑定到右值 (1)。`F&amp;&amp;` 很特殊,因为 `F` 是一个模板参数,因此这是一个所谓的_转发引用_,具有特殊的推导规则,可以绑定任何值类别。 (2认同)