2017-03-03 29 views
1

是否可以使用一些关键字来编译两个或多个C++函数内容的变体,这些关键字指示根据函数调用者执行的内容,而不需要为每个调用者创建多个完整函数副本?基于调用者的C++函数内容

到目前为止,解决方案一直使用函数和语句的参数来执行,具体取决于调用者。

V sol::compare(uchar start_lev, V *a , V *b){ 
solMutex.lock(); // not needed by all callers 
for(auto lev:solVec){ 
switch (lev.group){ 
case a: 
dontRemove=0; 
val++; // not used by all callers 
return something; 
case b: 
val++; //not used by all callers 
return something; 
case c: 
     etc... 
} 
#ifdef QT_DEBUG // not needed by all callers 

如果可以编写一个函数,并添加一些关键字,所以编译其他一些变化,而不依赖于不同的来电功能的未使用部分的开销。

+0

这就是参数的用途:函数根据函数调用做不同的事情。否则,函数无法以某种方式神奇地确定是谁调用它。 –

+2

您是否在寻找模板?给我们一个你想写的代码的简要示例。 –

+0

它对于程序的性能密集部分,并且会根据调用者使用4个功能改变的版本。 – Flow

回答

1

我不知道什么是交易,并在最后的宏,但你可以做你想做这样的东西:

template <bool do_lock, bool do_increment> 
V sol::compare(uchar start_lev, V *a , V *b){ 
    if (do_lock) solMutex.lock(); // not needed by all callers 
    for(auto lev:solVec){ 
    switch (lev.group){ 
    case a: 
     dontRemove=0; 
     if (do_increment) val++; // not used by all callers 
     return something; 
    case b: 
     if (do_increment) val++; //not used by all callers 
     return something; 
    case c: 
     etc... 
} 

要调用该方法,你会然后做

auto v = sol::compare<false, false>(....); 

并根据特定的调用者是否需要它来改变这些布尔值。请注意,在编译时知道您提供的布尔值,因为编译器正在为每个布尔值组合生成一个不同的函数。因为布尔编译器在编译时已知,所以这些分支将(如果布尔是错误的)简单地被任何编译器修剪为死代码。

+0

感谢您的信息,模板似乎是让easyer维护代码的好方法。 – Flow

1

您随后在评论中给出了几个想法的草图。

V sol::compare(uchar start_lev, V *a , V *b) { 
    solMutex.lock(); // not needed by all callers 
    for(auto lev:solVec){ 
     switch (lev.group){ 
      case a: 
       dontRemove=0; 
       val++; // not used by all callers 
       return something; 
      case b: 
       val++; //not used by all callers 
       return something; 
      case c: 
       ///etc... 
     } 
     #ifdef QT_DEBUG // not needed by all callers 
} 

对于预处理器来说,你可以用代码来做很多事情。

除此之外,你可以使用布尔值。有替代品。

对于其他模式,您可以将通用性和差异性分开。 例如,如果solMutex是一些虚构sol调用的成员变量,我们可以有一个lockingSol

class sol 
{ 
public: 
    V sol::compare(uchar start_lev, V *a , V *b); 
     for(auto lev:solVec){ 
      //etc 
     } 
    } 
}; 


class lockingSol 
{ 
public: 
    V compare(uchar start_lev, V *a , V *b) 
    { 
     solMutex.lock(); 
     return sol_.compare(start_lev, a, b); 
    } 

private: 
    mutex solMutex; 
    sol sol_; 
}; 

这使得nonlockingSol调用solMutex.lock();,然后调用sol_的方法。

模板和stragey设计模式为您提供切换行为的方法。

或者,您可以发送函子或lambda来发现算法中发生的情况。标准库iteself提供了很多这样的例子。

例如,考虑

template< class RandomIt, class Compare > 
void sort(RandomIt first, RandomIt last, Compare comp); 

这种迭代的东西,呼叫者在Compare功能将改变迭代里面发生了什么。