如果您有這樣的類模板:
template <typename T, unsigned CAPACITY>
class Collection
{
T m_array[CAPACITY]{};
T m_dummy{};
unsigned m_size{};
}
public:
void display(std::ostream& ostr = std::cout) const
{
ostr << "----------------------" << std::endl;
ostr << "| Collection Content |" << std::endl;
ostr << "----------------------" << std::endl;
}
而且我想根據使用的型別而不是容量來創建專業化,這可能嗎?
我有這個,它有效:
void Collection<Pair, 50u>::display(std::ostream& ostr) const
{
ostr << "----------------------" << std::endl;
ostr << "| This is a Pair |" << std::endl;
ostr << "----------------------" << std::endl;
}
當它被稱為:
Collection<Pair, 50> colDictionary;
但這僅在型別為 Pair 并且確切的 CAPACITY 為 50 時才有效。
這就是我的想法,允許 type 為 Pair 和 CAPACITY 為任何東西:
void Collection<Pair>::display(std::ostream& ostr) const
{
ostr << "----------------------" << std::endl;
ostr << "| This is a Pair |" << std::endl;
ostr << "----------------------" << std::endl;
}
但這會導致“類模板的引數太少”錯誤。
有什么方法可以在不更改實際類模板本身的情況下做到這一點?
uj5u.com熱心網友回復:
它被稱為部分模板專業化:
template <class T, unsigned Capacity>
struct Collection {
};
template <unsigned Capacity>
struct Collection<Pair, Capacity> {
// Specialize
};
需要注意的一點是,您不能部分專門化單個函式。你必須專門化整個類模板,如果類模板很長,這很煩人。如果您想專門化單個函式,另一種快速而骯臟的方法是僅使用“編譯時 if”:
#include <type_traits>
template <class T, unsigned Capacity>
struct Collection {
void display() const {
if constexpr (std::is_same_v<T, Pair>) {
// pair implementation
} else {
// general implementation
}
}
};
或者,作為一個更干凈的解決方案,嘗試將整個內容移出類并添加一個簡單的多載:
// Free-standing overloads:
template <class T, unsigned Capacity>
void diplay(Collection<T, Capacity> const& c) { /* ... */ }
template <unsigned Capacity>
void display(Collection<Pair, Capacity> const& c) { /* ... */ }
// The member function delegates the work to
// the overloaded functions. No template specialization
// is involved:
template <class T, unsigned Capacity>
struct Capacity {
void display() const {
display(*this); // calls the correct overload.
}
};
uj5u.com熱心網友回復:
做一個部分規范似乎很困難。
一些方法有助于您實作它:
- 為這種型別的情況定義一個規范類。
- 如果您只希望自定義此行為(但不是太多且受到限制),您可以使用 if-constexpr 分支。
- 如果您想避免使用類部分模板(因為重寫所有代碼是一種負擔),那么使用全域函式模板會很有幫助。
給出了一些建議的代碼:
#include <iostream>
template <typename T, unsigned capacity>
class Collection {
public:
void display(std::ostream &ostr = std::cout) const;
};
template <typename T, unsigned c>
void Collection<T, c>::display(std::ostream &ostr) const {
if constexpr (c == 50u) {
ostr << "Specification! \n";
} else {
ostr << "Normal Realization. \n";
}
}
int main() {
Collection<int, 50> c;
c.display();
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/486135.html
上一篇:用默認引數推導可變引數模板引數
