2015-11-04 110 views
2

我有問題實現像下面這樣的結構。這個想法是,我在某個頭文件中定義了一個實用函數,它分配了某種資源。爲了減輕客戶自己解放它的必要性,我想將它包裝成一個智能指針。 不幸的是,我不知何故需要刪除類型的客戶端,並有麻煩轉發 - 適當地聲明它。我現在的解決方案看起來像這樣,導致多個定義錯誤,因爲刪除程序是重新定義的,每增加一個包含utility.h如何轉發聲明自定義unique_ptr

這是我正在尋找的優雅解決方案嗎?

// utilities.h 
namespace foo 
{ 
    auto del = [](MyResource* res) { Deallocate(res); }; 
    std::unique_ptr<MyResource, decltype(del)> getResource(); 
} 

// utilities.cpp 
namespace foo 
{ 
    std::unique_ptr<MyResource, decltype(foo::del)> getResource() 
    { 
    return std::unique_ptr<MyResource, decltype(foo::del)>(Allocate(), del); 
    } 
} 
+1

使刪除器成爲一個*函數*而不是一個lambda對象變量,並將該函數標記爲'inline'? –

+0

@JoachimPileborg這應該是一個答案。 OTOH,它可以防止這種'unique_ptr'的默認構造。 – Angew

回答

0

我建議Angew's answer在這個主要是因爲類型擦除的std::function的額外開銷。不過不知道這種方式是可行的。


解決方法是簡單:在報頭具有聲明,在源具有定義:

// utilities.h 
namespace foo { 
    using del_t = std::function<void(MyResource *)>; 
    extern del_t del; 
    std::unique_ptr<MyResource, del_t> getResource(); 
} 

// utilities.cpp 
namespace foo { 
    del = [](MyResource* res) { 
     Deallocate(res); 
    }; 
    std::unique_ptr<MyResource, del_t> getResource() { 
     return std::unique_ptr<MyResource, del_t>(Allocate(), del); 
    } 
} 
+0

這會在'std :: function'中引入類型擦除的額外開銷。 – Angew

+0

@Angew是的。不知道任何其他方式來指定lambda的類型。如果這是一個問題,他應該去做一個簡單的功能。 – bolov

5

使用,而不是一個拉姆達一個普通的類:

部首:

namespace foo { 

    struct Deleter { 
    void operator() (MyResource *res) const { Deallocate(res); } 
    }; 

    std::unique_ptr<MyResource, Deleter> getResource(); 
} 

來源:

namespace foo 
{ 
    std::unique_ptr<MyResource, decltype(foo::del)> getResource() 
    { 
    return std::unique_ptr<MyResource, Deleter>(Allocate()); 
    } 
} 

這還有一個好處,就是在創建指針—時不必指定刪除器,默認構造的Deleter就可以了。

+0

是的,你的方式更好 – bolov