std::vector<std::string> names = transform(
filter(people, is_female),
name
);
|
管道操作符
std::vector names = people | filter(is_female) | transform(name);
++
操作符auto& operator++()
{
//移动迭代器
++m_current_position;
//从下一个元素开始搜索
m_current_position = std::find_if(m_current_position,
m_current_position,
m_end,
m_predicate
);
return *this;
}
++
操作符没有重载,而是重载了 *
解引用操作符auto operator*() const
{
//获取源集合中的元素,对他施加转换函数
//并把它作为代理迭代器指向的返回值
return m_function( *m_current_position);
}
std::vector<std::string> words =
read_text() | action::sort
| action:unique;
|=
操作符进行左结合运算
std::vector<std::string> words = read_text();
words |= action::sort | action:unique;
std::accumulate(
std::istream_iterator<double>(std::cin),
std::istream_iterator<double>(),
0
);
std::istream_iterator()
检测是否达到集合末尾,类似哨兵的迭代器 std::accumulate
将一直读取输入中的值,直到遍历迭代器和末端迭代器相同template <typename T>
bool operator==(const std::istream_iterator<T>& left,
const std::istream_iterator<T>& right)
{
if (left.is_sentinel() && right.is_sentinel())
{
return true;
}
else if (left.is_sentinel())
{
...
}
else if (right.is_sentinel())
{
...
}
else
{
...
}
}
view::ints(1)
view::ints(1)
应用示例//Range 示例为 std::vector
template <typename Range>
void write_top_10(const Range& xs)
{
auto items =
//将电影 range 和从1开始的整数无限 range 压缩在一起
//得到一个键值对的 range,电影名字和下标
view::zip(xs, view::ints(1))
//取出一个键值对,构造一个包含电影分级和电影名字的字符串
| view::transform([] (const auto& pair) {
return std::to_string(pair.second) +
" " + pair.first;
})
//只对前10部电影感兴趣
| view::take(10);
for (const auto& item: items) {
std::cout << item << std::endl;
}
}
view::zip
接收两个 range,并对两个元素进行匹配,得到一个元素对std::unique_ptr
不理想,使用 std::shared_ptr
std::pair
(对) 和 std::tuple
(元组)std::pair
是两种类型的乘积std::tuple
可以包含任意多的类型std::tie
std::pair
和 std::tuple
的用途是创建乘积类型,可以自动获取字典比较运算符bool operator<(const person_t& left, const person_t& right)
{
return std::tie(left.m_surname, left.m_name) <
std::tie(right.m_surname, right.m_name);
}
dynameic_cast
效率不高std::variant
代替继承实现和类型std::variant
不是基于动态多态,所以它不会保存指向推中对象的指针
std::get
和 std::get_if
访问其中的值
std::get(m_state);
std::get_if<1>(&m_state);
std::get
要么返回一个值,要么在获取不到时抛出异常std::get_if
返回指向被包含值的指针,或出错时返回nullstd::variant
优点
std::variant
掌握std::any
类,它是任意类型值的安全容器。
std::variant
低,不应该作为 std::variant
的简单类型替换std::variant
中的索引成员函数
m_state.index() == 0
get_if
和索引获取状态,因为状态类的成员函数只用在这一状态时才会被调用
std::unique_ptr
std::shared_ptr
std::optional
get_if
template<typename T, typename Variant>
std::optional<T> get_if(const Variant& variant)
{
T* ptr = std::get_if<T>(variant);
if (ptr)
{
return *ptr;
}
else
{
return std::nullopt;
}
}
class tennis_t
{
enum class points
{
love,
fifteen,
thirty
};
enum class player
{
player_1,
player_2
};
struct normal_scoring
{
points player_1_points;
points player_2_points;
};
struct forty_scoring
{
player leading_player;
points other_player_scores;
};
};
class tennis_t
{
struct deuce {};
struct advantage
{
player player_with_advantage;
};
};
class tennis_t
{
std::variant<normal_scoring, forty_scoring, deuce, advantage> state_;
};
std::visit
函数
std::variant
实例和一个对 std::variant
中的值操作的函数std::vistit([] (const auto& value) {
std::cout << value << std::endl;
}, state_);
template <typename... Fs>
struct overloaded : Fs... { using Fs::operator()...; };
template <typename... Fs> overloaded(Fs...) -> overloaded<Fs...>;
return std::visit(overloaded {
[] (init_t) {
return (unsigned)0;
},
[] (const running_t& state) {
return state.count();
},
[] (const finished_t& state) {
return state.count();
}
}, m_state);
visitor
模式更高效void point_for(player which_player)
{
Match(m_state)
{
Case(C<normal_scoring>()) //增加分数或切换状态
Case(C<forty_scoring>()) //玩家获胜或切换到平局
Case(C<deuce>()) //却换占先状态
Case(C<advantage>()) //玩家获胜,或切换回平局状态
}
EndMatch
}