我想創建一個與輸入 vieweable_ranges 一起使用的 to_vector 函式。如果輸入視圖和輸出向量具有完全相同的型別,我可以輕松地使其作業,但如果輸出需要對輸入范圍的元素進行 const 轉換,則無法使其作業。就我而言,輸入范圍具有非常量指標,但輸出可能指定常量指標。我想像這樣使用它:
auto a = to_vector( view ); // returns a vector<obj *>. This case is easy
vector<const obj *> b = to_vector( view ); // returns a vector of const pointers. This gives error shown at the end
標準庫在制作向量時轉換指標沒有問題
vector<const obj *> c( view.begin(), view.end() );
但我無法創建模板化函式來使其作業。我嘗試了很多變體,但我認為我最接近的想法是這樣的:
#include <ranges>
#include <vector>
using namespace std::ranges;
template <range Range, typename T = range_value_t<Range>> // default element type, T, based on input range
inline std::vector<T> to_vector(Range&& r) { // idea: user specifies T. (doesn't work)
std::vector<T> v;
if constexpr (std::ranges::sized_range<T>) {
v.reserve(std::ranges::size(r));
}
std::copy(std::ranges::begin(r), std::ranges::end(r), std::back_inserter(v));
return v;
}
to_vector 可以編譯,但是當我嘗試要求一個帶有類似錯誤的向量輸出時出現錯誤:
無法將 std::vector<Obj *,std::allocator<Obj *>>' 轉換為 'std::vector<const Obj *,std::allocator<const Obj *>>
uj5u.com熱心網友回復:
按照 Dominic Price 的建議,我將模板函式拆分為兩個單獨的函式。第一個適用于所有物件,但可能有一個稍微麻煩的呼叫約定。第二個使用 const 指標,并且很難獲得 std::views 的型別。
template <range R, typename T = range_value_t<R> >
inline auto to_vector(R &&r) {
return std::vector<T>(r.begin(), r.end()); // treats sized ranges correctly
}
template <range R, typename T>
inline auto to_vector(R &&r, T &&) {
return std::vector<T>(r.begin(), r.end()); // treats sized ranges correctly
}
這允許呼叫者使用以下語法,如下所示:
struct Unit {};
using UnitPtr = Unit const *;
using Units = vector<UnitPtr>;
unordered_set<Unit *> clusters; // clusters could even be a rvalue view
auto u = to_vector(clusters); // will return vector<Unit *>
Units v = to_vector<Clusters, UnitPtr>(clusters); // need typenames...
Units w = to_vector(clusters, UnitPtr()); // ... or this for convertable
這可能具有可以構造引數 T 的缺點。我的用途僅用于指標,所以不是問題。
uj5u.com熱心網友回復:
這是因為您的函式創建了一個 type 的回傳值std::vector<Obj*>,它確實與std::vector<const Obj*>; 所以除非std::vector提供了一個多載的建構式,它接受了自己的非常量版本,否則這種轉換是不可能的。回傳值不是由您將函式的結果分配給的值推匯出的,而是由T模板引數推匯出的,因此如果您使用以下命令顯式呼叫該函式,這將起作用T=const Obj*
您需要顯式多載該函式以構造 const 物件的向量,方法是傳遞一個虛擬標簽引數、一個額外的模板引數或一個to_const_vector函式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/375299.html
