2017-05-17 32 views
1

この質問How to pass template function with default arguments to std::call_onceに加えて、関数ポインタを使用するときにデフォルトの引数を渡して解決されましたが、実際のコードでこの解決策を試したところ、 STDにオーバーロード関数を扱う場合 std :: call_onceでオーバーロードされた関数を使用する方法

std::once_flag flag; 
class LifeTrackerHelper 
{ 
public: 
template<class T> 
inline static int SetLongevity(std::unique_ptr<T>& pobj,unsigned int longevity = 0) 
{ 
    return 0; 
} 
template<class T> 
inline static int SetLongevity(unsigned int longevity = 0) 
{ 
    return 0; 
} 

}; 
template<class T> 
class Singleton 
{ 
    public:  
    inline static T* getInstance() 
    { 
    static std::unique_ptr<T> ptr(new T()); 
    std::call_once(flag,&LifeTrackerHelper::SetLongevity<T>,std::ref(ptr),0); 
    //static int i = LifeTrackerHelper::SetLongevity<T>(ptr); 
    // if call_once is commented and above line uncommented this will work 
    return ptr.get(); 
    } 
}; 
class Test 
{ 
    public: 
    void fun() 
    { 
     std::cout<<"Having fun...."<<std::endl; 
    } 
}; 
; 
int main() 
{ 
    Singleton<Test>::getInstance()->fun(); 
    return 0; 
} 

だから、特別なルールがある::なcall_once

+0

ラムダを 'std :: call_once'パラメータとして使うのはなぜですか? – WhiZTiM

+1

'std :: call_once(フラグ、[&ptr] {LifeTrackerHelper :: SetLongevity(ptr、0);}); ' –

答えて

2

あなたが意味オーバーロードを指定するためにstatic_cast<>()を使用することができます。また、1つのオーバーロードされた関数です。たとえば、

std::call_once(flag, 
     static_cast<int (*)(std::unique_ptr<T>&, unsigned int)>(
       &LifeTrackerHelper::SetLongevity<T>), 
     std::ref(ptr), 0); 

同じ効果のために一時変数を使用することもできます。

int (*initfn)(std::unique_ptr<T>&, unsigned int) = 
     &LifeTrackerHelper::SetLongevity<T>; 
std::call_once(flag, initfn, std::ref(ptr), 0); 
+0

これは、より良いアプローチがない、かなり不愉快に見える – Kapil

+0

@Kapilあなたはコメントのセクションを読んでましたか? –

+0

はい、今のところ私はそのアプローチを使用していますが、関数ポインタだけでより良いことができるかどうかを知りたい – Kapil

関連する問題