Home > Enterprise >  Defining a struct method with function parameter in C
Defining a struct method with function parameter in C

Time:03-06

Looking at C interface code. I do not have access to the implementation. I made a small example to show the behavior.

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);
     }
};

Can somebody explain to me what is the usage of enumerate struct function member in this struct definition?

Based on my understanding the enumerate in this struct can take a function type as input parameter (function pointer?)

  1. Does it mean that whenever we create an object of MessageInfo struct we can call this method like below?
  2. How can define the function type, In other words what should i use instead of "???" in following code?
  3. What is the advantage of this model of coding (more specifically about enumerate method)?
MessageInfo messageInfo (1000, "A", "B");
    
messageInfo.enumerate<???>(printFrom(messageInfo.From);
      
void printFrom(string f) {
     cout<<"the msgInfo is sent from "<<  f<<endl;
}

CodePudding user response:

It expects you to pass a generic callable, e.g. a lambda. You don't have to specify the template argument. It can be deduced from the function argument.

For example:

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

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

messageInfo.enumerate(printFields);

which should print

Value of this field is 1000.
Value of this field is A.
Value of this field is B.

As you can see from this, enumerate can be used to apply the same operation to every member without having to repeat yourself for each one.

The signature is a bit unusual. You would normally expect F or F&& instead of F&. With either F or F&& you could put the lambda expression directly into the call instead of having to store it in a variable first.

  • Related