理解复杂的typedef表达式

时间:2016-11-23 14:07:43

标签: c++ c++11

我想知道这个表达意味着什么?

typedef bool (*compareShapes)(const Shape* s1, const Shape* s2);

Shape是一个类。

7 个答案:

答案 0 :(得分:25)

您应该使用using语句。它使同样的声明更容易阅读:

using compareShapes = bool(*)(const Shape*, const Shape*);

现在看?类型在等号后面。它是指向函数类型的指针。

也可以这样声明:

// function pointer type --v----------------------------------------------------v
using compareShapes =      std::add_pointer_t< bool(const Shape*, const Shape*) >;
//                    function signature  -----^------------------------------^

函数签名的组成如下:

<return-type>( <arguments...> )

当你在其中添加指针时,它看起来像这样:

<return-type>(*)( <arguments...> )

如果您在此处添加指针名称或类型名称,请在星号后添加:

<return-type>(*typeOrPointerName)( <arguments...> )

答案 1 :(得分:15)

嗯,它是一个typedef,所以有两个部分 - 类型和为它定义的新名称。

第一部分是类型:

bool (*)(const Shape* s1, const Shape* s2);

这是一个指向函数的指针,带有两个指向const-Shape的指针,并返回bool。

第二部分是类型的名称:compareShapes。不可否认,函数指针typedef很难阅读,但这部分仅仅是因为函数指针语法不经常使用。

因此,例如,我可以编写任意数量的兼容函数:

bool identical(const Shape *a, const Shape *b);
bool strictlyContained(const Shape *a, const Shape *b);
bool topologicallyEquivalent(const Shape *a, const Shape *b);

告诉我a是否与b相同,或完全位于b内,或者ab是否具有相同数量的孔。

然后,我可以编写适用于任何比较的代码,并选择稍后使用的代码,例如:

compareShapes cmp;
if (shouldUseIdentityComparison()) {
  cmp = &identical;
} else if (shouldUseInsideComparison()) {
  cmp = &strictlyContained;
} else {
  cmp = &topologicallyEquivalent;
// ...
if (cmp(a,b)) {
    // they're equal, for whichever comparison we chose above
}

现代代码中可能更常见的是编写模板,采用任意比较器类型(如std::sort),或编写采用std::function<bool(const Shape*, const Shape*)>的非模板函数,这比原始函数指针更灵活。

C没有(并且早期版本的C ++没有)具有这些功能,因此不得不使用函数指针。我怀疑它们主要用于与旧代码的向后兼容性,并且可能在资源受限的环境中使用。

答案 2 :(得分:12)

compareShapes是函数指针的别名,它接受2 const Shape*并返回bool

compareShapes func = [] (const Shape* s1, const Shape* s2) -> bool {
    return *s1 == *s2; //something boolean
};
bool result = func(s1, s2);

或者另一个例子,如果你已经有了功能:

bool someFunc(const Shape* s1, const Shape* s2) { return true; }
compareShapes funcPtr = someFunc;
bool result = funcPtr(s1, s2);

有关函数指针的更多信息,请访问HERE

答案 3 :(得分:5)

在评论中添加一些细节:

这是一个函数指针。 typedef可以让它更容易使用。通常,typedef的格式为&#34; typedef actual_type new_easier_name&#34;。例如:

typedef int i

显然这条线在实践中永远不会出现。但对于更复杂的类型(特别是涉及指针和模板的类型),使用typedef可以使代码更具可读性。

这个表达式给出了名称&#34; compareShapes&#34;到函数指针类型。在这种情况下,该类型是一个函数,它接收指向两个Shape对象的指针并返回一个布尔值。这样,将函数分配给指针并调用它的代码就更清楚了。

这是一个可能出现在实践中的例子。假设Shape至少有两个字段:周长和面积。用户可能希望对其中任何一个进行排序:

#include <vector>

bool perimeterComparison(const Shape* a, const Shape* b){        
    return a->perimeter <= b->perimeter;
}

bool areaComparison(const Shape* a, const Shape* b){
    return a->area <= b->area;
}

//Note the capitalization of CompareShapes to show it is a type, not a variable
typedef bool (*CompareShapes)(const Shape* a, const Shape* b);

void sortShapes(std::vector<Shape*>& shapes, CompareShapes comparison){
    //Lazy programming: bubble sort
    for(int first = 0; first < shapes.length(); shapes++){
        for(int second = first + 1; second < shapes.length(); shapes++){
            if(!comparison(shapes[first], shapes[second])){
                Shape* temp = shapes[second];
                shapes[second] = shapes[first];
                shapes[first] = shapes[second];
            }
        }
    }
}

int main(){
    //This could just as easily point to perimeterComparison or something else valid
    CompareShapes compareFunction = &areaComparison;

    std::vector<Shape*> shapes(10);
    for(int i = 0; i < 10; i++){
        shapes[i] = new Shape(); //Initialize the shapes somehow
    }

    sortShapes(shapes, compareFunction);

    for(int i = 0; i < 10; i++){
        cout << shapes[i] << "\n";
    }

    return 0;
}

答案 4 :(得分:2)

您可以使用cdecl来解释这些类型,但是您需要在类名前面插入struct,并替换它bool以解析为C代码:

cdecl> explain struct bool (*compareShapes)(const struct Shape* , const struct Shape* )
declare compareShapes as pointer to function (pointer to const struct Shape, pointer to const struct Shape) returning struct bool

然后,您需要在精神上撤消该转换,并提供

  

声明compareShapes作为指向函数的指针(指向const Shape的指针,指向const Shape)返回bool

答案 5 :(得分:1)

compareShapes是一个函数指针,它接受2个类型的参数(指向Shape的指针)并返回布尔值。

您可以为compareShapes分配符合此签名的任何功能。

例如,

bool isShapesValid(const Shape* s1, const Shape* s2) 

可以分配:

compareShapes objCompareShapes = &isShapesValid;

答案 6 :(得分:0)

typedef bool (*compareShapes)(const Shape* s1, const Shape* s2);
bool CmpShapes(const Shape *s1,const Shape *s2){retunr true;}

compareShapes是一个比较两个Shape对象的函数原型(签名)

例如:

class Shape{};
class CTest{
     compareShapes m_cmp;
 public:
     CTest(compareShapes _cmpFunc):m_cmp(_cmpFunc){
         printf("m_cmp: %p %s\n",m_cmp,m_cmp(NULL,NULL)?"true":"false");
     };
 };

void main(){
       Ctest tst(&CmpShapes);//we pass CmpShapes address.
}