簡體   English   中英

如何使用模板類的子面板來推斷C ++中模板函數的模板參數?

[英]how to use a sublass of a template class to deduce the template parameters of a template function in C++?

這可能很愚蠢...

如果我有這樣的模板類A,

template <class T1, class T2>
struct A
{
    T1 a;
    T2 b;
};

然后一個函數起作用

template <class T1, class T2>
void foo(A<T1, T2> *p)
{
}

現在我將A子類化

struct B : A<int, int>
{
};

B b[100];

我無法推斷出模板參數...

foo(b);

我必須這樣寫

foo((B *)b);

或像這樣

foo<int, int>(b);

現在,我希望foo可以接受A以外的其他T並將其視為A

template <class T>
struct A<T, void>
{
    T a;
};

template <class T>
void foo(T *p)
{
    foo((A<T, void> *)p);
}

現在,除非我這樣寫,否則以后的foo被稱為...

foo<int, int>(b);
  1. 如何使從子類數組中推導模板參數更容易?
  2. 查找重載函數時,如何使子類具有比其他類更高的優先級?

這似乎會做

template <class T>
struct is_A_derived
{
    typedef char (&yes)[1];
    typedef char (&no)[2];

    template <class T1, class T2>
    static yes test(A<T1, T2> *);
    static no test(...);

    template <class T1, class T2>
    static A<T1, T2> get_type(A<T1, T2> *);
    static A<T, void> get_type(...);

    template <class T1, class T2>
    static A<T1, T2> base_type(A<T1, T2> *);
    static int base_type(...); // guess or maybe hope this "int" is never used

    static const bool value = sizeof(test((T *)0)) == sizeof(yes);
    static const bool identical = value && sizeof(base_type((T *)0)) == sizeof(T);

    typedef typename std::conditional<identical, decltype(get_type((T *)0)), A<T, void>>::type type;
};

請注意,此代碼失敗。 您不能多態使用C樣式數組(無論模板如何)。

也就是說,您不能將B數組視為A數組。

p[1]怎樣? 好吧,以下是內部發生的情況:

*(p + 1)

指針算術。 現在, + 1被編譯器進一步轉換為sizeof A字節的增量。 但是您的數據結構不是sizeof A大,而是sizeof B 因此p[1]將指向內存中的錯誤位置。

因此,編譯器正在(完全是無意間!)通過禁止此調用來做正確的事情。

在第一種情況下,如果您碰巧對A *指針執行指針算術運算,實際上就有將B數組衰減到A *指針的危險。

讓我感到驚訝的是,它無法解決,但可能是一個不錯的安全功能,以防萬一您打算對A數組執行某項功能,而對B數組不起作用。

您可以執行foo( &b[0] )而不是強制轉換或顯式模板化。

在后一種情況下,如果您的T *與A模板上的函數具有相同的名稱,則現在會使事情復雜化,並且T *上具有函數foo。

一旦添加了第二個foo,對B的調用實際上將選擇第二個foo,因為它現在成為了完美匹配。 可以通過巧妙的SFINAE技術為子類賦予更高的優先級,以查看其是否為A。 通常,除非確實需要,否則我會避免使用此選項。

暫無
暫無

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

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