std::vector已知滿足 a 的要求RandomAccessContainer,因此使用[]運算子是常數時間。但是,std::list只滿足 aContainer和的較弱要求ReversibleContainer,因此檢索一個元素是 O(N),而且該[]運算子不存在。
我想約束一個模板,以便在[]運算子不存在或不是 O(1) 時得到一個很好的編譯時錯誤。我怎樣才能做到這一點?
目前,在 g 11.2.0 上,當使用以下模板實體化以下模板時,我無法收到干凈的錯誤訊息std::list:
template<typename RandomAccessContainer>
void foo(RandomAccessContainer const & x);
template<typename ContiguousContainer>
void foo(ContiguousContainer const & x);
template<typename T>
requires ContiguousContainer<T>
void foo(T const & x);
uj5u.com熱心網友回復:
您可以從型別特征開始檢查該型別是否支持下標:
template<class T>
struct has_subscript {
static std::false_type test(...);
template<class U>
static auto test(const U& t) -> decltype(t[0], std::true_type{});
static constexpr bool value = decltype(test(std::declval<T>()))::value;
};
template <class T>
inline constexpr bool has_subscript_v = has_subscript<T>::value;
然后添加概念:
template <class T>
concept subscriptable = has_subscript_v<T>;
template <class T>
concept subscript_and_cont_iterator =
std::contiguous_iterator<decltype(std::begin(std::declval<T>()))> &&
subscriptable<T>;
演示
如果您不需要型別特征,只需subscriptable使用一個requires子句:
template <class T>
concept subscriptable = requires(const T& c) { c[0]; };
演示
uj5u.com熱心網友回復:
Ranges 庫帶有一堆與范圍相關的概念。在這種情況下,您需要:
template <std::ranges::random_access_range R>
void foo(R&& x);
這個概念不檢查范圍本身是否有[](無論如何這對你來說是不夠的,map提供但不是隨機訪問),但它確實檢查迭代器是否是隨機訪問迭代器,并且隨機訪問迭代器本身是必需的支持索引。
所以而不是x[2]你必須寫ranges::begin(x)[2]。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/433864.html
下一篇:RestClient和執行緒鎖定
