2012-11-17 47 views
3

我试图通过并理解一个使用内在速度的卡方方案。在这个过程中,我遇到了一些我无法理解的代码。神秘的C++语法

我曾尝试审查教科书,谷歌和搜索这个网站没有运气。我认为问题在于,在不了解语法的任何内容的情况下,我无法充分描述搜索的术语或关键字以获得任何相关结果。

这里是代码行,我不明白:

float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float; 

这里是包含它的功能:

float chi2_float(const int dim, const float* const x, const float* const y) { 
    float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float; 
#ifdef __SSE__ 
    chi2_float = chi2_intrinsic_float; 
#endif 
    return chi2_float(dim, x, y); 
} 

在我看来,这可能是声明和定义一个函数,当我注释掉该行并重新编译时,我得到:

错误C2659:'=':作为左操作数的函数 在线 chi2_float = chi2_intrinsic_float;

如果需要,我可以发送包含此函数的.h文件,但它与您对参数期望的一样。

任何帮助将不胜感激。

+3

不那么神秘;它只是一个函数指针。方便地使用C++教科书? –

回答

11

根据__SSE__的值,该行正在将类型函数指针的变量设置为其他两个函数之一。

然后调用chi2_float指向的函数并返回结果。

+0

谢谢dma。现在我知道它是一个我明白的类型函数指针。 –

7

此:

float (*chi2_float)(const int, const float*, const float*)= chi2_baseline_float; 

声明的函数指针名chi2_float并分配给它一个指向名为chi_baseline_float功能。

然后,如果定义了__SSE__宏,则会使用指向函数chi2_intrinsic_float的指针重新分配指针。

所有这一切的最终效果是类似的东西:

float chi2_float(const int dim, const float* const x, const float* const y) 
{ 
#ifdef __SSE__ 
    return chi2_intrinsic_float(dim, x, y); 
#else 
    return chi2_baseline_float(dim, x, y); 
#endif 
} 
+3

相似,但不相同。不幸的是,问题中的代码效率不高,因为通过函数指针进行调用,这不仅增加了间接级别,而且阻止了任何可能的内联优化。您比较的代码应该更快,并且我建议OP尽可能使用此示例代替他的代码。 – cdhowie

+0

+1。更清洁,更短,更好,更快。你怎么会失去? –

+0

谢谢迈克尔伯尔。我正在采纳你的建议并重做代码。这是更清洁和可以理解的。 –

1

你的问题的代码有一些意见:

// beginning of the definition of function chi2_float 
float chi2_float(const int dim, const float* const x, const float* const y) { 
    // declare the variable chi2_float as a function pointer 
    // set variable chi2_float to the address of the function chi2_baseline_float 
    float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float; 
// if macro __SSE__ is defined (if the compiler enables SSE instructions set) 
// [this is your case because you got an error in the below line when you have commented the above line] 
#ifdef __SSE__ 
    // then preprocessor adds the following line that sets again the variable chi2_float (but to another function) 
    chi2_float = chi2_intrinsic_float; 
#endif 
    // call the function pointed by the variable chi2_float 
    return chi2_float(dim, x, y); 
} 
+0

感谢olibre您的意见非常具有说明性,并使“神秘”的语法易于理解。 –

+0

不客气@JamesCrow ;-)很快又见到另一个问题/答案;-) – olibre

1
float chi2_float(const int dim, const float* const x, const float* const y) { 
    float (*chi2_float)(const int, const float*, const float*) = chi2_baseline_float; 
#ifdef __SSE__ 
    chi2_float = chi2_intrinsic_float; 
#endif 
    return chi2_float(dim, x, y); 
} 

难看。

修复此代码的第一件事是使用除函数名以外的其他名称作为函数指针变量的名称。我认为这个变量影响了这个函数的名字,这是詹姆斯克罗混乱的根源。

修复此代码的第二件事是完全摆脱函数指针,导致代码Michael Burr张贴在他的答案中。

+0

感谢David Hammen。你是对的,我认为让函数名和函数指针变量名相同是我的困惑。 –

1

迈克尔·伯尔建议如下:

float chi2_float(const int dim, const float* const x, const float* const y) 
{ 
#ifdef __SSE__ 
    return chi2_intrinsic_float(dim, x, y); 
#else 
    return chi2_baseline_float(dim, x, y); 
#endif 
} 

忽略编译器的片刻优化器;这可能会得到改善。 Burr先生的解决方案使用两个函数调用:main()(或其他)调用chi2_float(),然后调用相应的实现。这可以减少到只有一个函数调用有以下:

#ifdef __SSE__ 
    #define chi2_float(dim, x, y) chi2_intrinsic_float(dim, x, y) 
#else 
    #define chi2_float(dim, x, y) chi2_baseline_float(dim, x, y) 
#endif 

同样的结果或许能在声明伯尔先生的chi2_float()为“内联”来实现。然而,回到现实世界(编译器主动优化代码),你会期望一个好的优化器去除额外的函数调用,从而使得Burr先生的解决方案一样快。

为了完整性,我发布了这个讨论。尽管这对Burr先生的解决方案没有改进,但它增加了更多的上下文。从技术上讲,它应该是一个评论,而不是一个新的答案,但不可能在评论中对源代码进行格式化。这就是人生。

+0

谢谢Michael J给你答案。我正在按照Michael Burr的建议改变代码。我也可能会将代码减少到一个函数调用,但我需要首先更好地理解整体逻辑。 –