![](/img/trans.png)
[英]c++ partial specialization: How can I specialize this template<class T1, class T2> to this template<class T1>?
[英]C++ partial template specialization: how to specialize std::iterator_category
我想編寫模板 function void foo() ,它需要 2 個迭代器或指針。
我想要一個專門用於 random_access_iterator 的版本。 我試着像下面這樣寫:
// generic version
template<class Iter, typename std::iterator_traits<Iter>::iterator_category>
void foo(Iter first, Iter last);
// Specialized version for random_access_iterator
template<class RandomIter>
void foo<RandomIter, std::random_access_iterator_tag>(RandomIter first, RandomIter last)
{
}
它給出錯誤:非法使用顯式模板 arguments
請讓我知道定義它的正確方法是什么。 謝謝
您不能部分專門化功能模板。 部分專業化僅適用於類模板。 您可以做的就是只有一個函數模板,該函數模板委派給適當專門化的類模板的static
成員,例如
template <typename Iter,
typename = typename std::iterator_traits<Iter>::iterator_category>
struct foo_impl {
static void call(Iter first, Iter last);
};
template <typename Iter>
struct foo_impl<Iter, std::random_acces_iterator_tag> {
static void call(Iter first, Iter last);
};
templlate <typename Iter>
void foo(Iter first, last) {
foo_impl<Iter>::call(first, last);
}
或者,您可以使用部分排序。 在那種情況下,有兩個函數模板,一個以通用迭代器類別作為參數,另一個以特定類別作為參數。 類別或指向它的指針作為附加參數傳遞。 我認為這也需要轉發功能(我通常使用的方法是使用類模板的部分專業化方法)。
基於“標簽分發”模式,我為我的問題寫了一個解決方案:
// Using "= delete" on un-supported categories to get concise compile-time error information
template<typename Iter> void _foo(Iter first, Iter last, std::bidirectional_iterator_tag) = delete;
template<typename RandomIter>
void _foo(RandomIter first, RandomIter last, std::random_access_iterator_tag)
{ ... }
template<class Iter>
void foo(Iter first, Iter last)
{
typename std::iterator_traits<Iter>::iterator_category category;
_foo(first, last, category);
}
現在可以使用了。 如果有錯誤或需要改進,請發表評論。 謝謝。
作為對先前答案的補充,使用更新的 C++ 標准版本實現相同結果的方法。
您可以使用if constexpr
:
#include <iterator>
#include <type_traits>
template<class Iter>
void foo(Iter first, Iter last)
{
using Cat = typename std::iterator_traits<Iter>::iterator_category;
if constexpr (std::is_same_v<Cat, std::random_access_iterator_tag>) {
// random access iterator
}
else if constexpr (std::is_same_v<Cat, std::bidirectional_iterator_tag>) {
// bidirectional iterator
}
else if constexpr (std::is_same_v<Cat, std::forward_iterator_tag>) {
// forward iterator
}
else if constexpr (std::is_same_v<Cat, std::input_iterator_tag>) {
// input iterator
}
}
您可以重載 function 並使用概念區分每種情況:
#include <iterator>
template<std::random_access_iterator Iter>
void foo(Iter first, Iter last)
{
// random access iterator
}
template<std::bidirectional_iterator Iter>
void foo(Iter first, Iter last)
{
// bidirectional iterator
}
template<std::forward_iterator Iter>
void foo(Iter first, Iter last)
{
// forward iterator
}
template<std::input_iterator Iter>
void foo(Iter first, Iter last)
{
// input iterator
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.