2017-06-10 138 views
5

違反ODR在從生產線上圖書館閱讀代碼,我發現這樣的事情如何避免與traits類

Traits.hpp

template <typename Type> 
class Traits { 
    template <typename T, 
       detail::EnableIfIsInstantiation<T, Type>* = nullptr> 
    static void foo(T& object) { 
     object.foo(); 
    } 
}; 

SpecialTraits.hpp

template <> 
class Traits<Special> { 
    static void foo(Special& object) { 
     object.foo(); 
    } 
    static void foo(Special&& object) { 
     object.special_foo(); 
    } 
}; 

如果庫實例化使用的類型,將導致ODR違例for Something在一個翻譯單元中不包括SpecialTraits.hpp,然後實例化在另一個翻譯單元中使用專門特徵的類型。當這兩個翻譯單元連接在一起時,這將導致ODR違規。

建議如何避免此問題?我是否必須訴諸於在原始Traits.hpp文件中包含所有專業?如果我不允許編輯Special的定義文件,該怎麼辦?

注意請忽略foo()可能已經在&&情況下,由專業本身Special的事實。我想不出一個更好的例子。

+1

將專業化放在與'Special'定義相同的標題中。 –

+0

@PeteBecker好想法!我應該在問題中包括這一點。但如果你沒有訪問權限呢?例如,假設這是一個「boost」模塊的專門化 – Curious

+0

在具有專業化的標題中包含具有聲明的標題,並且只包含以後的更高版本。 –

回答

3

將專業化放在「WidgetWrapper.hpp」而不是「Widget.hpp」中,並在所有地方包含「WidgetWrapper.hpp」。否則,請用Boost提交錯誤報告,並期望它不會出現,因爲這個確切的problem在15年前被討論過,沒有解決方案。