我正在撰寫一個類,例如 std::vector 可以由 n 值或迭代器 [first, last) 構造,示例代碼如下:
template<typename T>
class Test1{
public:
Test1(size_t n, const T& v){
data_ = new T[n];
for(size_t i = 0; i < n; n){
data_[i] = v;
}
}
template<typename Iterator>
Test1(Iterator first, Iterator last){
size_t n = std::distance(first, last);
data_ = new T[n];
while(first != last){
*data_ = *first ;
}
}
Test1(){
if(nullptr != data_){
delete[] data_;
data_ = nullptr;
}
}
T* data_;
};
用法:
Test1<int> t1(2, 0);
std::vector<int> vec{1, 2, 3};
Test1<int> t2(vec.begin(), vec.end());
但編譯錯誤:
...
In instantiation of Test1<T>::Test1(Iterator, Iterator) [with Iterator = int; T = int]
error: invalid type argument of unary
...
所以我的問題是如何實作這兩個功能,為什么模板無法編譯以及如何更改它(限制迭代器型別)?
uj5u.com熱心網友回復:
代碼無法編譯,因為t1試圖呼叫迭代器建構式。
C 20
解決這個問題的最簡單方法是簡單地使用 C 20 概念std::input_iterator,如下所示:
template<std::input_iterator Iterator>
Test1(Iterator first, Iterator last){
size_t n = std::distance(first, last);
data_ = new T[n];
while(first != last){
*data_ = *first ;
}
}
此外,您將需要洗掉初始化指標 ( data_(n, v)) 和遞增i而不是n在 n 值建構式中的無效嘗試。
C 11
首先,我們需要一些額外的實用程式:
template <typename T, typename = void>
struct is_iterator {
static constexpr bool value = false;
};
template <typename T>
struct is_iterator<T, decltype(*std::declval<T>() , void())> {
static constexpr bool value = true;
};
此自定義型別特征使用 SFINAE 來檢查提供的型別是否可以遞增和取消參考(與您在代碼中執行的方式相同)。
你可以像這樣使用它:
template<typename Iterator, typename std::enable_if<is_iterator<Iterator>::value, bool>::type = true>
Test1(Iterator first, Iterator last){
size_t n = std::distance(first, last);
data_ = new T[n];
while(first != last){
*data_ = *first ;
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/425942.html
上一篇:jq更新json檔案中的布林值
下一篇:如何處理和遍歷這個串列?
