簡體   English   中英

在模板特化中強制編譯時錯誤

[英]Force a compile time error in a template specialization

我最近開始學習現代模板元編程,我自己寫了一個index_of函數用於類型。

template<std::size_t Index, class C, class A> struct mp_index_of_impl{};
template<std::size_t Index, class C,template<class...> class A,class ...Ts>
struct mp_index_of_impl<Index,C,A<C,Ts...>>{
    using type = std::integral_constant<std::size_t,Index>;
};
template<std::size_t Index, class C,template<class...> class A,class ...Ts,class T1>
struct mp_index_of_impl<Index,C,A<T1,Ts...>>{
    using type = typename mp_index_of_impl<Index + 1,C,A<Ts...>>::type;
};
template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
    //static_assert(false,"Does not contain type");
    using type = std::integral_constant<std::size_t,0>;
};

問題是我上次的專業化

template<std::size_t Index, class C,template<class...> class A> 
struct mp_index_of_impl<Index,C,A<>>{
      //throw a compile error here
};

我試着像這樣使用static_assert

template<std::size_t Index, class C,template<class...> class A> struct mp_index_of_impl<Index,C,A<>>{
    static_assert(false,"Does not contain type");
};

但是每次都會拋出一個編譯錯誤,即使它不匹配。

如果匹配此模板特化,我想拋出一個帶有自定義錯誤消息的編譯錯誤。 我該怎么做?

如果將static_assert(false,...)放在模板特化中,那么始終無法從中生成有效代碼。 這是不正確的,不需要診斷

解決此問題的方法是使static_assert依賴於模板參數:

template<typename T>
struct assert_false : std::false_type
{ };

template <typename T>
inline T getValue(AnObject&)
{
    static_assert( assert_false<T>::value , "Does not contain type");
}

要在這里獲得一個真正完善的解決方案有點煩人。 你正在遇到[temp.res] / 8:

如果無法為模板生成有效的特化,並且未實例化該模板,則模板格式錯誤,無需診斷...如果緊接其定義后的模板的假設實例化將由於不依賴於模板參數的構造,程序是不正確的; 無需診斷。

所以我們需要做的是避免任何可能做static_assert(false, ...)事情。 在這種情況下,我們有一個部分開放。 我們可以專注於我們只剩下一種類型並斷言這是我們正在尋找的情況:

template<std::size_t Index, class C,template<class...> class A, class Last>
struct mp_index_of_impl<Index,C,A<Last>>{
    static_assert(std::is_same<C, Last>::value,"Does not contain type");
    using type = std::integral_constant<std::size_t, Index>;
};

這不會處理空列表的情況,但是對於頂層級別,您可以為非空白添加另一個static_assert

template<std::size_t Index, class C,template<class...> class A>
struct mp_index_of_impl<Index,C,A<>>{ };

template <typename T> is_empty : std::false_type { };
template <template <class...> class A> is_empty<A<>> : std::true_type { };

template <class C, class X>
struct mp_index_of
: mp_index_of_impl<0, C, X>
{
    static_assert(!is_empty<X>::value, "Does not contain type");
};

雖然在實踐中, TartanLlama的解決方案可能會讓每個編譯器都能得到你,但我可能只是使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM