簡體   English   中英

為模板類的某些模板參數添加成員?

[英]Add a member for certain template parameters of a template class?

考慮一個模板類:

template <class First, class Second, class Third, class Fourth>
class MyClass;

為某些模板參數集添加成員函數的正確方法是什么?

例如,當Secondstd::string()時,如何添加成員f() std::string()

這是我找到的方法,我通常使用以下方法:

#include <iostream>
#include <type_traits>
#include <array>

template <class Container>
struct Array
{
    Container data;
    template <class... Dummy, 
              class = typename std::enable_if<sizeof...(Dummy) == 0>::type,
              class = typename std::enable_if<
                               std::tuple_size<
                               typename std::conditional<sizeof...(Dummy), 
                                                         Container, 
                                                         Container
                                                         >::type
                               >::value == 1
                               >::type
              >
    inline typename Container::value_type& value(Dummy...)
    {return data[0];}
};


int main()
{
    Array<std::array<double, 0>> array0; // Does not have the value() member
    Array<std::array<double, 1>> array1; // Have the value() member
    Array<std::array<double, 2>> array2; // Does not have the value() member
    Array<std::array<double, 3>> array3; // Does not have the value() member
}

它工作得很好,但是它是一種元編程技巧,而不是一種干凈/標准的方法。

您可以使用繼承和專業化。 就像是:

template <typename T> struct Helper2 {};

template <> struct Helper2<std::string>
{
    void f() {};
};

template <class First, class Second, class Third, class Fourth>
struct MyClass : public Helper2<Second>
{
    // Normal code.
};

int main()
{
    MyClass<std::string, int, std::string, std::string> c1;
    MyClass<int, std::string, int, int> c2;
    //c1.f();     // this is an error
    c2.f();    // this works
    return 0;
}

在您的聲明中,我不太明白“ Dummy的目的。 可以使用功能參數列表中根本不使用的兩個默認模板參數來完成此操作:

#include <type_traits>
#include <string>

template <class First> // arguments ommited for brevity
struct MyClass {
    template<
        typename U = First,
        typename = typename std::enable_if< std::is_same<U, std::string>::value >::type
    >
    void f() {}
};

int main()
{
    MyClass<int> c1;
    MyClass<std::string> c2;
    // this is an error
    // c1.f();
    c2.f();    // this works
}

現場示例。

請注意,可能會作弊: c1.f<std::string>(); 仍然可以。

在C ++ 1y概念TS中,我們有requires子句,這些子句可以讓您輕松地做到這一點。 參見http://isocpp.org/files/papers/n3929.pdf-但是我可能是錯的。

在C ++ 1y之外,由於所有功能template 必須至少具有一個有效的專長,因此您的技術會使您的程序變形,無需進行診斷。 碰巧的是,這是一個很少執行的要求,因為在一般情況下解決“沒有有效的專業化”涉及解決暫停問題。 盡管如此,程序員有責任確保所有template函數都至少具有一組有效的template參數。

我發現對於C ++ 11中的零參數函數嚴格合法的方法是使用基於CRTP的類特化,從而消除了CRTP基類特化中的方法。

另一種方法是創建一個私有的,不可訪問的類型,並使其成為在要禁用它的情況下創建合法專業化的唯一方法。 然后在班級內部可以作弊,但在課堂上則不能作弊。

暫無
暫無

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

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