2016-09-20 33 views
1

假設我們有一個函數,其中AB是用戶定義類型的兩個重載:分解出一個重載函數調用

void f(A &a, B *b); 
void f(B *b); 

我們也有一個功能對應的重載實現算法:

void alg(A &a, B *b) { 
    // ... some code calling f(a,b) 
} 

void alg(B *b) { 
    // ... same code as alg(A &a, B *b), with f(a,b) replaced by f(b) 
} 

有沒有一種方法來分解撥打電話f避免在這種情況下的代碼重複?如果你不能使用C++ 11像拉姆達功能,只需使用仿函數或抽象類的地方拉姆達的

版本與仿函數(

template<typename T> 
static function doAlg(T fct) 
{ 
    // Common code, use fct() instead of f(a,b) or f(b) 
} 

void alg(A &a, B*b) 
{ 
    doAlg([&a, b](){ f(a,b); }); // when doAlg call fct(), it will call f(a,b); 
} 

void alg(B*b) 
{ 
    doAlg([b](){ f(b); }); // when doAlg call fct(), it will call f(b); 
} 

+0

http://stackoverflow.com/questions/6829241/perfect-forwarding-whats-it-all-about? – user3159253

+1

@ user3159253在這種情況下,我看不出有多完美的轉發幫助。請特別注意,參數的數量因過載而異。 – AlwaysLearning

+0

你想盡量減少哪些代碼?來源還是編譯? 'alg(...)'除了將它們傳遞給'f(...)'之外還使用它的參數嗎? – Deduplicator

回答

3

一個可能的解決方案是使用拉姆達如果你不能/不想使用拉姆達):

struct CallFWithAB 
{ 
    CallFWithAB(A &a, B *b): 
     _a(a), _b(b) 
    {} 

    A &_a; 
    B *_b; 

    void operator()() 
    { 
     f(_a,_b); 
    } 
} 

struct CallFWithB 
{ 
    CallFWithAB(B *b): 
     _b(b) 
    {} 

    B *_b; 

    void operator()() 
    { 
     f(_b); 
    } 
} 

template<class T> 
static function doAlg(T& fct) 
{ 
    // Common code, use fct() instead of f(a,b) or f(b) 
} 

void alg(A &a, B*b) 
{ 
    CallFWithAB caller(a,b); 
    doAlg(caller); // when doAlg call fct(), it will call f(a,b); 
} 

void alg(B*b) 
{ 
    CallFWithB caller(b); 
    doAlg(caller); // when doAlg call fct(), it will call f(b); 
} 
+0

'doAlg()'可以模板化以避免需要構建'std :: function' –

+0

@RichardHodges的權利,我每次都會忘記它。更正 – Garf365

+0

@RichardHodges對不起,可能愚蠢的問題。我不明白節省的是多少。 – AlwaysLearning

3

您可以使用完美轉發帶有可變參數模板:

template <typename... Args> 
void alg(Args&&... args) 
{ 
    // ... 

    f(std::forward<Args>(args)...); 

    // ... 
} 
+0

非常好的解決方案。我沒有選擇它的唯一原因是我想保持我的參數列表與其他實現類似'alg'成員函數的類一致。 – AlwaysLearning