[英]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.