当前位置:网站首页>RI Geng series: tricks of using function pointers

RI Geng series: tricks of using function pointers

2022-06-24 03:02:00 mariolu

One 、 What is a function pointer

A function pointer It's a kind of C、C++、 Other categories C The pointer to language .

C Language standards , Function indicator (function designator, That is, the function name ) Neither lvalue , Nor is it an R-value . but C++ Language standards specify that function indicators belong to lvalues , Therefore, the conversion of the function indicator to the right value of the function pointer belongs to the conversion of the left value to the right value .

Two 、 Function pointer application

Function pointers are used to abstract interfaces . Mask function implementation process .

The most classic example is the size of two objects .

typedef (bool)(*CompareFuncT) (struct Object, struct Object);
struct Object&
select(struct Object A, struct Object B, CompareFuncT compare) {
    if (compare(A, B)) return A;
    else return B;
}

Here you can pass in various comparison functions , Just follow CompareFuncT Interface functions .

This interface function can be a normal function , Static function of class , Can member functions of a class ?

3、 ... and 、 Can I use a member function of a class as a function pointer

Let's take another example :

We have 1 An interface class , And implementation classes that implement interface classes .

so what , We operate on him manipulate, This operation will traverse all the implementation classes , And use this to call the interface implemented by each class . Look at the pseudo code

class TrancatedCalculator {
    virtual bool IsTrancated(std::shared_ptr<Context>&, Item&){};
}
class FilterActiveApp : public TrancatedCalculator {
    bool IsTrancated(std::shared_ptr<ScheduleRankContext>&, Item&) override;
}

void do() {
    std::vector<std::unique_ptr<TrancatedCalculator>> truncated_calculator_vec;
    for (auto& calculator: truncated_calculator_vec) {
        truncated_calculator_vec->IsTruncated(item);
    }
}

Okay , Here we continue to expand do The logic of , Then I think we need to follow the single blame principle of function . And then in do There is another one inside truncate function , And then put truncated_calculator_vec->IsTrancated Pass on the past , Whether this is feasible , Can you write like this ?

void foo(IsTruncatedFuncT fn, Item item) {return;}

void do(){
    std::vector<std::unique_ptr<TrancatedCalculator>> truncated_calculator_vec;
    for(auto& calculator: truncated_calculator_vec){
        //truncated_calculator_vec->IsTruncated(item);
        foo(truncated_calculator_vec->IsTruncated, item);// Can you write it like this ? The answer is no 
    }
}

Obviously it can't be written like this ,

One problem that needs to be explained here is “ Member pointer ” Instead of ordinary function pointers .

A member pointer to a function is more than just a function pointer . On the implementation side , The compiler cannot use simple function addresses , Because you don't know the address to call ( Think about virtual functions ). Of course , You also need to know the object to provide this Implicit parameter .

If you want to provide a function pointer to existing code , You should write static member functions of your classes . Static member functions do not require this, So you need to pass this object as an explicit parameter .

But what if you have to pass in a member function , Because sometimes member functions change some member variables of a class , Can't be static .

We can design it like this :

 bool
 has_truncated(std::unique_ptr<TrancatedCalculator>& tc,  std::shared_ptr<Context>& ctx, Item& item) {
     return tc->IsTrancated(ctx, item);
 }

Then we pass in except has_truncated Outside the function pointer , You need to bring in std::unique_ptr<TrancatedCalculator>& object . And then here we are foo Can design

 void foo(IsTruncatedFuncT fn, std::shared_ptr<Context>& ctx,
         std::unique_ptr<TrancatedCalculator>& tc, Item& item) {
     fn(tc, ctx, item);
 }
原网站

版权声明
本文为[mariolu]所创,转载请带上原文链接,感谢
https://yzsam.com/2021/10/20211021003857521B.html