简体   繁体   English

函数返回C ++ 11中的函数指针

[英]Function returning function pointer in C++11

I have the following C code : 我有以下C代码:

inline void ChooseNext ( std::vector<RLS> & rls_vec_left_to_choose_,
           int & num_files_left_to_choose_, const int algo_,
           std::vector<RLS> & rls_vec_chosen_ )
{
if ( ( num_files_left_to_choose_ > 0 )
 && ( rls_vec_left_to_choose_.size ( ) > 0 ) )
  {
    switch ( algo_ )
      {
      case kAlgo1 :
        std::sort ( rls_vec_left_to_choose_.begin ( ), rls_vec_left_to_choose_.end ( ), SortFunc1 );
        break;
      case kAlgo2 :
      default:
        std::sort ( rls_vec_left_to_choose_.begin ( ), rls_vec_left_to_choose_.end ( ), SortFunc2 );
        break;
      }
      // etc
   }
 }

Where the sort functions are all of the type : sort函数的所有类型都是:

bool SortFunc1 ( const RLS & d1, const RLS & d2 ) ;

How do I change it to a function that takes const int algo_ and returns a bool (*) ( const RLS & d1, const RLS & d2 ) and then remove the switch case in this function ? 如何将其更改为一个带有const int algo_的函数并返回一个bool (*) ( const RLS & d1, const RLS & d2 )然后删除此函数中的switch case? I am trying to do it in as readable a manner as possible, and hopefully using C++11 features. 我试图以尽可能可读的方式进行,并希望使用C ++ 11功能。

If C++, why return a function pointer? 如果是C ++,为什么返回一个函数指针? You can use std::function instead: 您可以使用std::function代替:

std::function<bool(const RLS &, const RLS &)> ChooseNext(int algo)
{
    static const std::vector<std::function<bool(const RLS &, const RLS &)>> st {
        SortFunc1,
        SortFunc2,
        // etc.
    };

    return st[algo]; // assuming that `algo` goes from 0 to st.size()
}

If you really need a function pointer, then here's how you declare a function returning a function pointer: 如果你真的需要一个函数指针,那么这里是你如何声明一个函数返回一个函数指针:

bool (*ChooseNext())(const RLS &, const RLS &)
{
    // whatever
}

Although there is some advantage to using std::function<bool(RLS const&, RLS const&) , it is interesting to create a function returing a function pointer. 虽然使用std::function<bool(RLS const&, RLS const&)有一些优点,但创建一个函数返回函数指针很有意思。 The easiest but also most boring approach is to use a typedef : 最简单但也最无聊的方法是使用typedef

typedef bool (*CompareFunction)(RLS const&, RLS const&);
CompareFunciton getFunction(int algo) {
    switch (algo) {
    case kAlgo1: return &SortFunc1;
    case kAlgo2: return &SortFunc2;
    default: assert("algo selection value out of range");
    }
    return &SortFunc1; // ... or somehow deal with the situation
 }

OK, I'm not interested in dealing with the selection of the actual function but only with how the getFunction() is declared. 好吧,我对处理实际函数的选择并不感兴趣,而只关注如何声明getFunction() There are obviously several ways how you can deal with algo being out of range ( assert() , throw , use a default, ...). 显然有几种方法可以处理algo超出范围( assert()throw ,使用默认值,......)。 For the rest I'm not going to change the implementation but just the declaration. 其余的我不会改变实现,只是声明。

What can be done with a typedef can also be done without! 使用typedef可以做什么也可以不用! So, here is the C++03 version without using a typedef : 所以,这里是不使用typedef的C ++ 03版本:

bool (*getFunction(int algo))(RLS const&, RLS const&) { ... }

OK, that looks plain weird but you can think of it as replacing the typedef with the actual function. 好吧,这看起来很奇怪,但你可以把它想象为用实际函数替换typedef。 To read what it does you need to read types right to left and inside out. 要阅读它的内容,您需要从右到左阅读类型。 No matter what, the above declaration is, mildly put, hideous. 无论如何,上述声明都是温和的,可怕的。 With C++11 it is possible to use trailing return types: 使用C ++ 11,可以使用尾随返回类型:

auto getFunction(int algo) -> bool(*)(RLS const&, RLS const&) { ... }

That notation is, I think, quite readable. 我认为这种符号非常易读。 Using a trailing return type for the function pointer can be done but doesn't necessarily improve readability, I think (but then, I may be just too old-school): 使用函数指针的尾随返回类型可以完成,但不一定提高可读性,我想(但是,我可能只是太老了):

auto getFunction(int algo) -> auto (*)(RLS const&, RLS const&) -> bool { ... }

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

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