2016-07-29 17 views
0

可有人請,解釋1)爲什麼下面的代碼不會對鐺2)究竟應該如何改寫工作是鏗鏘兼容動態鏈接上鐺失敗的完全專用的模板constexpr靜態成員

using LinkWeight = float; 

template <bool WEIGHTED=true> 
struct InpLink { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 
    Weight weight; //!< Link weight 
    // ... 
}; 

template <> 
struct InpLink<false> { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 
    constexpr static Weight weight = 1; 
}; 

此代碼工作在GCC罰款,但對Linux操作系統Ubuntu的x64上鐺3.8.1鏈接錯誤:

未定義的參考`InpLink ::重」

定義之後:

template <> 
constexpr typename InpLink<false>::Weight InpLink<false>::weight; 

編譯時錯誤是:extraneous 'template<>' in declaration of variable 'weight'

定義之後:

template <bool WEIGHTED> 
constexpr typename InpLink<false>::Weight InpLink<false>::weight; 

編譯時錯誤是:

..cluster.hpp:31:60: error: redefinition of 'weight' as different kind of symbol 
constexpr typename InpLink<false>::Weight InpLink<false>::weight; 
                 ^
..cluster.h:58:27: note: previous definition is here 
     constexpr static Weight weight = 1; 

它看起來像一個鐺錯誤...

注:同樣的例子正常工作在CLang上,如果我在模板中有2個參數,則執行部分特化並將靜態constexpr權重定義爲:

template <bool TMP> 
constexpr typename InpLink<false, TMP>::Weight InpLink<false, UNSIGNED>::weight; 

template <bool WEIGHTED=true, bool TMP=true> 
struct InpLink { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 
    Weight weight; //!< Link weight 
    // ... 
}; 

template <bool TMP> 
struct InpLink<false, TMP> { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 
    constexpr static Weight weight = 1; 
}; 

很顯然,我不想使用額外的模板參數來克服鏈接錯誤。有沒有其他方法可以解決這個問題?
CLang 3.8.1有什麼問題或者我的完整模板專業化?

回答

0

因此,看起來這是CLang < = 3.8.1中的一個錯誤,它限制了動態庫中靜態成員的constexpr的使用,並且阻止了完全專用模板的靜態成員的單獨定義。
而要克服的方法是:
1.對於CLang,請使用static const而不是constexpr。
2.定義只有對應於模板聲明,而不是完整的專業化的靜態成員:

template <bool WEIGHTED=false> 
struct InpLink { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 

    //! Link is unweighted 
    constexpr static bool IS_WEIGHTED = false; 
    //! \copydoc SimpleLink<Weight>::weight 
    // ATTENTION: such complicated definition is required to overcome 
    // the linking error on CLang 
#ifdef __clang__ 
    const 
#else 
    constexpr 
#endif // __clang__ 
    static Weight weight 
#ifndef __clang__ 
     = 1 
#endif // !__clang__ 
    ; 
    // ... 
}; 

template <> 
struct InpLink<true> { 
    using Weight = LinkWeight; //!< \copydoc LinkWeight 
    Weight weight; //!< Link weight 
    // ... 
}; 

而且在定義的.cpp靜態重量不標頭,如:

#ifdef __clang__ 
// Note: Required by CLang for the linking 
template <> 
const InpLink<false>::Weight InpLink<false>::weight = 1; 
#endif // __clang__ 

PS GCC是真的比CLang更適合發佈版本的編譯器(CLang對調試還有一些獨特的優勢)。