iter_value_t<I> 用于实现间接可读类型的算法。 iterator_traits<I> 用于在迭代器方面实现算法。
间接可读类型是可以通过应用operator* 读取的类型。这包括指针、智能指针和迭代器。所有这些类型都满足indirectly_readable 概念。
要完全理解 iter_value_t<I> 背后的想法,我们需要看看它的实现。
如果std::iterator_traits<std::remove_cvref_t<T>> 不是特化的,那么std::iter_value_t<T> 就是std::indirectly_readable_traits<std::remove_cvref_t<T>>::value_type。否则为std::iterator_traits<std::remove_cvref_t<T>>::value_type。
您可以看到,如果可能的话,它会尝试默认为 iterator_traits,但还会将remove_cvref_t 转换应用于类型。这允许它使用 const-volatile-reference 限定类型,例如 const char* const 或 const char*& 等。
这对吗?
不,iterator_traits<I> 也可以处理概念(除非我误解了您的意思)。
#include <vector>
#include <iostream>
#include <concepts>
#include <type_traits>
#include <iterator>
template<class T>
concept my_iterator_concept =
std::is_same_v<typename std::iterator_traits<T>::value_type, int>;
int main()
{
std::vector<int> v;
std::cout << std::boolalpha << my_iterator_concept<typename decltype(v)::iterator>;
}
运行代码here。
我什么时候应该选择其中一个?
除非(不太可能)您对某些iterator_traits 功能有特殊需求,否则请与iter_value_t<T> 及其家族的其他成员一起使用,例如iter_reference_t 或iter_difference_t。
这是一个为什么你应该喜欢它的例子。这是deduction guide for basic_string view。
template<class It, class End>
basic_string_view(It, End) -> basic_string_view<iter_value_t<It>>;
您可能只想传递 const char* const 作为迭代器的替代方法,如下所示:
// Requires c++ 20
#include <string_view>
#include <iostream>
int main()
{
const char* const c = "example";
auto str = std::string_view(c, c + 3);
std::cout << str;
}
iterator_traits<I>::value_type 在这种情况下会失败。
运行代码here。
间接可读特征和迭代器特征的概念在标准中相互解释,可以在 (c++23 n4892 working draft) 中找到:
23.3.2.2 Indirectly readable traits
23.3.2.3 Iterator traits