簡體   English   中英

用於函數的常量模板 arguments

[英]Constant template arguments for functions

我定義了以下類型:

template <typename TType>
struct symbol{};

template <typename TAtom, unsigned IDim>
struct tensor_type {};

template <unsigned IDim>
using real = tensor_type<double, IDim>;

template <unsigned IDim>
using index = tensor_type<int, IDim>;

我現在想用這樣的類型符號實例調用函數:

template <template<typename TType, unsigned IDim> typename TTemplate, typename TType, unsigned IDim>
void f(symbol<TTemplate<TType, IDim>>* sym) {
    std::cout << "higher dimension" << std::endl;
}

int main() {
    symbol<real<0>>* p1 =  new symbol<real<0>>();
    symbol<index<0>>* p2 =  new symbol<index<0>>();
    symbol<real<1>>* p3 =  new symbol<real<1>>();
    symbol<index<5>>* p4 =  new symbol<index<5>>();

    f(p1); //dimension 0
    f(p2); //dimension 0
    f(p3); //higher dimension
    f(p4); //higher dimension
}

這工作得很好。 但是現在我想區分維度 0 和所有其他維度的符號,但我不知道如何使用模板正確聲明重載的 function 以實現這一目標。

我嘗試了以下方法:

template <typename TType>
void f(symbol<TType<0>>* sym) {
    std::cout << "dimension 0" << std::endl;
}

出現error: 'TType' is not a template ,並且

template <template<typename TType> typename TTemplate, typename TType>
void f(symbol<TTemplate<TType>>* sym) {
    std::cout << "dimension 0" << std::endl;
}

error: wrong number of template arguments (2, should be 1)

我不能在一個 function 中包含兩個維度的代碼,因為在實際實現中,維度 0 的類型與具有更高維度的類型具有不同的屬性,所以即使我在 function 中使用大小寫區別,編譯器也會抱怨有些通過 ZDBC11CAA58BDA9E7F7有需要的屬性。

一種可能是像這樣為維度 0 的每種可能類型聲明一個 function

void f(symbol<real<0>>* sym) {
    std::cout << "dimension 0" << std::endl;
}

但由於我在實際實現中有多種類型,並且所有函數看起來都完全相同(除了簽名),我想避免冗余代碼。

有什么方法可以更優雅地實現這一目標嗎?

在您顯示的示例中,只有一個相關的 class 模板: tensor_type

其他使用using聲明的只是這個的別名。 它們沒有定義新的 class 模板或類型。

因此,只需在重載中指定該模板就足夠了:

template <typename T>
void f(parameter_symbol<tensor_type<T, 0>>* sym) {
    std::cout << "dimension 0" << std::endl;
}

如果您有多個模板,其中一些您沒有顯示,那么

template <template<typename, unsigned> typename TTemplate, typename T>
void f(parameter_symbol<TTemplate<T, 0>>* sym) {
    std::cout << "dimension 0" << std::endl;
}

將工作。 請注意,模板模板參數template<typename, unsigned> typename TTemplate中的模板參數種類必須與您將用作參數的 class 模板匹配。 (作為一個例外,您也可以將unsigned替換為auto 。)

如果您有多個具有不同類型模板參數的模板,那么您需要為所有情況定義此類重載。 如果尺寸在參數列表中並不總是在同一個 position 中,那么這種方法是行不通的。


讓相關類提供指示尺寸的constexpr static 成員變量idim或返回它的constexpr static ZC1C425268E68385D1ABZ5074C17A94F1 會更簡單。 或者,一個專門的自由變量模板或 function 模板。

然后,您可以使用任何類型的 function 重載並通過 SFINAE 對其進行約束,或者如果您可以使用 C++20,則requires class:

template <typename T>
requires(T::idim == 0)
void f(parameter_symbol<T>* sym) {
    std::cout << "dimension 0" << std::endl;
}

暫無
暫無

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

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