簡體   English   中英

模板struct標簽部分特化與enable_if或類似的東西

[英]template struct tag partial specialisation with enable_if or something similar

我正在尋找一種方法來使用std :: enable_if或類似的東西來擴展已經存在的自定義點,它將像下面的A<T>一樣工作(只是一個虛擬的例子):

// customisation point structure in external lib
template<typename T>
struct A
{
    typedef T type;
};

//---------------------------------------------
#include <vector>

template <typename T>
concept bool Floating = std::is_floating_point<T>::value;

// specialisation with enable_if style that doesn't require change to external lib
template<Floating T>
struct A<T>
{
    typedef std::vector<T> type;
};

int main()
{
    static_assert(std::is_same<A<int>::type, int>::value, "");
    static_assert(std::is_same<A<float>::type, std::vector<float>>::value, "");

    return 0;
}

問題是我有以下限制:

  • struct A無法修改為接受兩個模板參數template<typename T, typename = void>因為此結構是在外部庫中定義的
  • 不能使用概念精簡版(因為有些人認為有必要將其標准化推遲到未來幾年......)
  • 不希望搞亂所有調用網站上的代碼,比如A<type_mod<float>>因為這樣會很丑陋且容易出錯(宏觀使用同樣如此)
  • 不想編寫外部代碼生成器

我懷疑這是可能的,但我記得過去的人說不需要概念精簡版,因為它們或多或少可以用元編程模擬,所以我希望有人可以證明我錯了。

為了確保我正確理解這個問題,你是在尋找與你發布的代碼相當的東西,但只使用C ++ 14(沒有概念)?

我認為你提到的第一個限制(“結構A不能被修改為接受兩個模板參數”)是最大的問題。 我不知道有任何方法可以在不使用概念的情況下同時為整個“類”類型(例如浮點類型)專門化現有的單參數模板。

所以我認為對你的問題的嚴格回答是,“不,這是不可能的。”

如果你可以修改A的第一個聲明,那么它會容易得多。 就個人而言,我覺得有時候對“我無法修改這個外部庫”的問題的最佳答案是“去看看如何修改它,然后回來再問你的問題。”

我在下面提供了一個替代解決方案的想法,但是您的問題中缺少太多信息,無法說明它是否適合您。

我假設這個外部庫提供了一些你提供的標題,以便查看你的專業化,並且每當你更改那個標題時你都會重新編譯庫。 (如果情況並非如此,請編輯您的問題以更好地解釋情況。)

在你想要專業化的同一個標題中,你可以考慮使用一些老式的預處理器技巧作為解決方法。 這很丑陋,你必須小心你的#include語句的順序,但它可能會為你完成工作:

// customisation point structure in external lib
template<typename T>
struct A
{
    typedef T type;
};

//---------------------------------------------
#include <vector>

template<typename T, bool is_float>
struct Av2impl
{
    typedef T type;
};

template<typename T>
struct Av2impl<T, true>
{
    typedef std::vector<T> type;
};

template<typename T>
struct Av2
{
    typedef typename Av2impl<T, std::is_floating_point<T>::value>::type type;
};

// force all code after this point to use Av2 instead of A
#define A Av2

int main()
{
    static_assert(std::is_same<A<int>::type, int>::value, "");
    static_assert(std::is_same<A<float>::type, std::vector<float>>::value, "");

    return 0;
}

暫無
暫無

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

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