SlideShare a Scribd company logo
1 of 77
Download to read offline
C++20 新功能:

Concepts & Ranges
吴咏炜
wuyongwei@gmail.com
2020
标准化的时间线
!2
Concepts
!3
⼀个例⼦
!4
template <typename N>
bool odd(N n)
{
return bool(n & 0x1);
}
template <Integer N>
bool odd(N n)
{
return bool(n & 0x1);
}
等价形式
!5
bool odd(Integer auto n)
{
return bool(n & 0x1);
}
template <typename N>
bool odd(N n)
requires(Integer<N>)
{
return bool(n & 0x1);
} 

为什么需要 Concepts?
To make requirement on types used as template arguments
explicit
Precise documentation
Better error messages
Overloading
!6
C++11 之前的标准化努⼒
Bjarne Stroustrup and Gabriel Dos Reis: Concepts — Design choices for template argument checking. October 2003. An early
discussion of design criteria for "concepts" for C++.
Bjarne Stroustrup: Concept checking — A more abstract complement to type checking. October 2003. A discussion of models of
"concept" checking.
Bjarne Stroustrup and Gabriel Dos Reis: A concept design (Rev. 1). April 2005. An attempt to synthesize a "concept" design based on
(among other sources) N1510, N1522, and N1536.
Jeremy Siek, Douglas Gregor, Ronald Garcia, Jeremiah Willcock, Jaakko Jarvi, and Andrew Lumsdaine: Concepts for C++0x.
N1758==05-0018. May 2005.
Gabriel Dos Reis and Bjarne Stroustrup: Specifying C++ Concepts. POPL06. January 2006.
D. Gregor, B. Stroustrup: Concepts. N2042==06-0012. June 2006. The basis for all further "concepts" work for C++0x.
Douglas Gregor, Jaakko Jarvi, Jeremy Siek, Bjarne Stroustrup, Gabriel Dos Reis, Andrew Lumsdaine: Concepts: Linguistic Support
for Generic Programming in C++. OOPSLA'06, October 2006. An academic paper on the C++0x design and its experimental
compiler "ConceptGCC."
Pre-Frankfurt working paper (with "concepts" in the language and standard library): http://www.open-std.org/jtc1/sc22/wg21/
docs/papers/2009/n2914.pdf . N2914=09-0104. June 2009.
B. Stroustrup: Simplifying the use of concepts. N2906=09-0096. June 2009.
!7
Concepts 没有进⼊ C++11 的原因
草案复杂
Concepts
Concept maps
Axioms
争议颇多
没有成熟实现
!8
Bjarne 对于 Concepts 的原则(2009)
鸭⼦类型
泛型编程模板成功的关键
不像⾯向对象⼀样需要明确使⽤接⼜
替换性
不会匹配/调⽤⽐“保证”的先决条件要求更⾼的函数
“意外匹配”是个⼩问题
不会是 C++ 的前 100 个问题
!9
(2015/11)
Concepts TS
!10
Concepts 没有进⼊ C++17 的原因
从 Concept TS 出版到标准定稿只有不到四个⽉的时间
概念只有⼀个实现(GCC)
Concept TS 规格书的作者和 GCC 中的概念实现者是同⼀个⼈;没
有⼈独⽴地从规格书出发实现概念
只有 Ranges TS 及其实现 cmcstl2 ⼤量使⽤了概念
Concept TS ⾥没有实际定义概念(Ranges TS ⾥有)
!11
(2017/7)
Concept TS merged into C++20 draft
!12
基本的概念
regular
semiregular
copyable
copy_constructible movable
move_constructible swappable
assignable_from
default_initializable
equality_comparable
!13
迭代器相关概念
semiregular
indirectly_readable indirectly_writableweakly_incrementable
input_or_output_iterator
input_iterator output_iterator
forward_iterator
bidirectional_iterator
random_access_iterator
totally_ordered
equality_comparable
contiguous_iterator
!14
CMCSTL2 ⾥的部分实际概念定义 I
template <class T, class U>
concept WeaklyEqualityComparable =
requires(const remove_reference_t<T>& t,
const remove_reference_t<U>& u) {
{ t == u } -> boolean;
{ t != u } -> boolean;
{ u == t } -> boolean;
{ u != t } -> boolean;
}; 

template <class T>
concept equality_comparable =
WeaklyEqualityComparable<T, T>;
!15
CMCSTL2 ⾥的部分实际概念定义 II
template <class T>
concept copyable =
copy_constructible<T> && movable<T> &&
assignable_from<T&, const T&>; 

template <class T>
concept semiregular =
copyable<T> && default_initializable<T>;
template <class T>
concept regular =
semiregular<T> && equality_comparable<T>;
!16
CMCSTL2 ⾥的部分实际概念定义 III
template <class I>
concept weakly_incrementable =
semiregular<I> &&
requires(I i) {
typename iter_difference_t<I>;
requires signed_integral<iter_difference_t<I >>;
{ ++i } -> same_as<I&>;
i ++;
}; 

template <class I>
concept input_or_output_iterator =
__dereferenceable<I&> && weakly_incrementable<I>; 

template <class I, class T>
concept output_iterator =
input_or_output_iterator<I> && writable<I, T> &&
requires(I& i, T && t) {
*i ++ = std ::forward<T>(t);
};
!17
Concepts 测试
#define TEST_CONCEPT(Concept, Type ...) 
cout << #Concept << '<' << #Type << " >: " << Concept<Type> << endl

TEST_CONCEPT(semiregular, std ::unique_ptr<int>);
TEST_CONCEPT(equality_comparable, std ::unique_ptr<int>);
TEST_CONCEPT(readable, int);
TEST_CONCEPT(readable, std ::unique_ptr<int>);
TEST_CONCEPT(writable, std ::unique_ptr<int>, int);
TEST_CONCEPT(semiregular, arma ::imat);
TEST_CONCEPT(assignable_from, arma ::imat&, arma ::imat&);
TEST_CONCEPT(semiregular, arma ::imat22);
TEST_CONCEPT(assignable_from, arma ::imat22&, arma ::imat22&);
TEST_CONCEPT(regular, int);
TEST_CONCEPT(regular, char);
TEST_CONCEPT(integral, int);
TEST_CONCEPT(integral, char);
!18
Concepts 测试结果
semiregular<std::unique_ptr<int>>: false
equality_comparable<std::unique_ptr<int>>: true
readable<int>: false
readable<std::unique_ptr<int>>: true
writable<std::unique_ptr<int>, int>: true
semiregular<arma::imat>: true
assignable_from<arma::imat&, arma::imat&>: true
semiregular<arma::imat22>: false
assignable_from<arma::imat22&, arma::imat22&>: false
regular<int>: true
regular<char>: true
integral<int>: true
integral<char>: true
!19
Sutton 的例⼦
template <typename R, typename T>
bool in(R const& r, T const& value)
requires range<R> && equality_comparable_with<T, typename R ::value_type>
{
for (auto const& x : r)
if (x == value)
return true;
return false;
}
vector<string> v{"Hello", "World"};
in(v, 0);
!20
出错信息
GCC 8.3 缺省输出
166 ⾏
Clang 9.0 缺省输出
82 ⾏
GCC 8.3 -std=c++17 -fconcepts 输出
sutton_example.cpp: In function 'int main()':
sutton_example.cpp:26:12: error: cannot call function 'bool in(const R&, const T&) requires range<R> and
equality_comparable_with<T, typename R::value_type> [with R = std::vector<std::__cxx11::basic_string<char> >; T =
int]'
in(v, 0);
^
sutton_example.cpp:13:6: note: constraints not satisfied
bool in(R const& range_, T const& value)
^~
sutton_example.cpp:13:6: note: in the expansion of concept 'equality_comparable_with<T, typename R::value_type>
template<class T, class U> concept const bool std::experimental::ranges::v1::equality_comparable_with<T, U> [with T
= int; U = std::vector<std::__cxx11::basic_string<char> >::value_type]'
!21
概念和重载
template <typename R>
bool in(R const& r, size_t value)
requires requires(R r) { r.size(); }
{
if (r.size() == value)
return true;
return false;
}
vector<string> v{"Hello", "World"};
in(v, "Hello");
in(v, 0);
!22
不使⽤ Concept 时的变通重载⽅法
template <typename _Fn, typename _T1, typename _T2>
constexpr auto fmap(_Fn && f, const std ::pair<_T1, _T2>& args);
template <typename _Fn, typename ... _Targs>
constexpr auto fmap(_Fn && f, const std ::tuple<_Targs ...>& args);
template <template <typename, typename> class _OutCont = std ::vector,
template <typename> class _Alloc = std ::allocator,
typename _Fn, class _Rng>
constexpr auto fmap(_Fn && f, _Rng && inputs) -> decltype(
begin(inputs), end(inputs),
_OutCont<
std ::decay_t<decltype(f(*begin(inputs)))>,
_Alloc<std ::decay_t<decltype(f(*begin(inputs))) >>>());
!23
另⼀个 SFINAE
template <class _T1, class _T2>
struct can_reserve {
struct good { char dummy; };
struct bad { char dummy[2]; };
template <class _Up, void (_Up ::*)(size_t)> struct _SFINAE1 {};
template <class _Up, size_t (_Up ::*)() const> struct _SFINAE2 {};
template <class _Up> static good reserve(_SFINAE1<_Up, &_Up ::reserve>*);
template <class _Up> static bad reserve( ...);
template <class _Up> static good size(_SFINAE2<_Up, &_Up ::size>*);
template <class _Up> static bad size( ...);
static const bool value = (sizeof(reserve<_T1>(nullptr)) == sizeof(good) &&
sizeof(size<_T2>(nullptr)) == sizeof(good));
};


template <class _T1, class _T2>
void try_reserve(_T1&, const _T2&, std ::false_type) {}
template <class _T1, class _T2>
void try_reserve(_T1& dest, const _T2& src, std ::true_type) { dest.reserve(src.size()); } 

try_reserve(result, inputs,
std ::integral_constant<bool, can_reserve<decltype(result), _Rng> ::value>());
!24
⽤ Concept 进⾏简化
template <typename _T1, typename _T2>
concept can_reserve =
requires(_T1& dest, const _T2& src) {
dest.reserve(src.size());
};


template <class _T1, class _T2>
void try_reserve(_T1&, const _T2&, std ::false_type) {}
template <class _T1, class _T2>
void try_reserve(_T1& dest, const _T2& src, std ::true_type) { dest.reserve(src.size()); }

try_reserve(result, inputs,
std ::integral_constant<bool, can_reserve<decltype(result), _Rng >>());
!25
⽤ if constexpr 进⼀步简化
template <typename _T1, typename _T2>
concept can_reserve =
requires(_T1& dest, const _T2& src) {
dest.reserve(src.size());
};
if constexpr (can_reserve<decltype(result), _Rng>) {
result.reserve(inputs.size());
}
!26
使⽤ Concepts 的问题
样例实现尚未跟上 Concepts 的标准
如代码中的“concept”在 GCC(到 9 为⽌)需要写“concept bool”
特定概念的定义和名称有⼩概率可能变化
CMCSTL2 已经跟随标准草稿进⾏了⼀次⼤规模更新
使⽤概念后能⼯作的代码可能会停⽌⼯作
如果对象使⽤了特殊技巧,不 regular 的话
概念的出错提⽰友好性部分被 -Wfatal-errors 抵消
!27
Concepts 总结
更简单
更表意
更可读
只有编译时开销
!28
Ranges
!29
⼀点历史
Boost.Range, 2003
D range, ~2009
Range-v3, 2013
Ranges TS, 2017
合并进 C++20, 2018
正式标准化, ~2020
!30
Ranges 之前的代码
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
std ::sort(std ::begin(a), std ::end(a));
std ::copy(std ::begin(a), std ::end(a),
std ::ostream_iterator<int>(
std ::cout, " "));
!31
Ranges ⽰例——排序
namespace ranges = std ::ranges;
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
ranges ::sort(a);
ranges ::copy(a, ranges ::ostream_iterator<int>(
std ::cout, " "));
!32
Ranges ⽰例——反向视图
namespace ranges = std ::ranges;
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
auto r = ranges ::reverse_view(a);
ranges ::copy(r, ranges ::ostream_iterator<int>(
std ::cout, " "));
!33
Ranges ⽰例——过滤视图
namespace ranges = std ::ranges;
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
auto r = ranges ::filter_view(a,
[](int i) { return i % 2 == 0; });
ranges ::copy(r, ranges ::ostream_iterator<int>(
std ::cout, " "));
!34
Ranges ⽰例——级联视图
namespace ranges = std ::ranges;
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
auto r = ranges ::reverse_view(
ranges ::filter_view(a,
[](int i) { return i % 2 == 0; }));
ranges ::copy(r, ranges ::ostream_iterator<int>(
std ::cout, " "));
!35
Ranges ⽰例——管道
namespace ranges = std ::ranges;
int a[] = {1, 7, 3, 6, 5, 2, 4, 8};
auto r = a
| ranges ::view ::filter(
[](int i) { return i % 2 == 0; })
| ranges ::view ::reverse;
ranges ::copy(r, ranges ::ostream_iterator<int>(
std ::cout, " "));
!36
想象 Unix 管道
do_something … | grep … | sort | uniq
!37
那到底什么才是⼀个 range?
!38
Range 的定义
template <class T>
concept _RangeImpl =
requires(T && t) {
ranges ::begin(static_cast<T &&>(t));
ranges ::end(static_cast<T &&>(t));
};
template<class T>
concept range = _RangeImpl<T&>;
!39
Range 相关的概念
input_range common_range
forward_range
bidirectional_range
random_access_range
output_range sized_range
contiguous_range
view
range
!40
semiregular
copyable default_initializable
view
template <class T>
concept view =
range<T> &&
semiregular<T> &&
enable_view< __uncvref<T >>;
!41
common_range
template <class T>
concept common_range =
range<T> &&
same_as<iterator_t<T>, sentinel_t<T >>;
!42
sized_range
template <class T>
concept sized_range =
range<T> &&
requires(T& r) { size(r); };
!43
output_range
template <class R, class T>
concept output_range =
range<R> &&
output_iterator<iterator_t<R>, T>;
!44
input_range
template <class T>
concept input_range =
range<T> &&
input_iterator<iterator_t<T >>;
!45
Sentinel 例⼦
struct null_sentinel {};
template <input_or_output_iterator I>
bool operator !=(I i, null_sentinel) { return *i != 0; }
//template <Iterator I>
//operator !=(null_sentinel, I i), operator ==, …

ranges ::for_each(argv[1], null_sentinel(),
[](char ch) { std ::cout << ch; });
!46
视图(View)
不(唯⼀)拥有元素(允许和其他 view 共同拥有)
常数时间拷贝、移动或赋值
⼤多数容器是 range,不是 view
C++17 string_view 满⾜ view 的条件,但 string 不满⾜
View 满⾜ semiregular,即 copyable 和 default_initializable
!47
Range 概念检查 I
!48
vector<int> const vector<int>
range ✓ ✓
view ✗ ✗
sized_range ✓ ✓
common_range ✓ ✓
output_range ✓ ✗
input_range ✓ ✓
forward_range ✓ ✓
bidirectional_range ✓ ✓
random_access_range ✓ ✓
contiguous_range ✓ ✓
Range 概念检查 II
!49
list<int> const list<int>
range ✓ ✓
view ✗ ✗
sized_range ✓ ✓
common_range ✓ ✓
output_range ✓ ✗
input_range ✓ ✓
forward_range ✓ ✓
bidirectional_range ✓ ✓
random_access_range ✗ ✗
contiguous_range ✗ ✗
Range 概念检查 III
!50
int [8] int const [8]
range ✓ ✓
view ✗ ✗
sized_range ✓ ✓
common_range ✓ ✓
output_range ✓ ✗
input_range ✓ ✓
forward_range ✓ ✓
bidirectional_range ✓ ✓
random_access_range ✓ ✓
contiguous_range ✓ ✓
Range 概念检查 IV
!51
reverse_view<int [8]> reverse_view<int const [8]>
range ✓ ✓
view ✓ ✓
sized_range ✓ ✓
common_range ✓ ✓
output_range ✓ ✗
input_range ✓ ✓
forward_range ✓ ✓
bidirectional_range ✓ ✓
random_access_range ✓ ✓
contiguous_range ✗ ✗
Range 概念检查 V
!52
filter_view<int [8]> filter_view<int const [8]>
range ✓ ✓
view ✓ ✓
sized_range ✗ ✗
common_range ✓ ✓
output_range ✓ ✗
input_range ✓ ✓
forward_range ✓ ✓
bidirectional_range ✓ ✓
random_access_range ✗ ✗
contiguous_range ✗ ✗
Range 概念检查 VI
!53
istream_line_reader take_view<istream_line_reader>
range ✓ ✓
view ✓ ✓
sized_range ✗ ✗
common_range ✓ ✗
output_range ✗ ✗
input_range ✓ ✓
forward_range ✗ ✗
bidirectional_range ✗ ✗
random_access_range ✗ ✗
contiguous_range ✗ ✗
Range 概念检查 VII
!54
iota_view(0) iota_view(0, 5) iota_view(0) | take(5)
range ✓ ✓ ✓
view ✓ ✓ ✓
sized_range ✗ ✓ ✗
common_range ✗ ✓ ✗
output_range ✗ ✗ ✗
input_range ✓ ✓ ✓
forward_range ✓ ✓ ✓
bidirectional_range ✓ ✓ ✓
random_access_range ✓ ✓ ✓
contiguous_range ✗ ✗ ✗
并⼊ C++20 的 Range
基于 D4128, Range-v3 和 Range TS
分离名空间来减少影响
std::ranges (之前是 std::experimental::ranges)
但基本概念仍然放在 std 名空间⾥
定义了很多概念 (concepts)
添加了视图 (views) 和视图适配器 (view adapters)
修改了标准算法 (algorithms)和⼯具 (utilities)
!55
修改了的算法
all_of
any_of
none_of
for_each
find*
mismatch
equal
is_permutation
search*
!56
copy*
move*
swap*
transform
replace*
fill
remove*
reverse*
rotate*
shuffle
sort*
nth_element
lower_bound
upper_bound
equal_range
binary_search
partition*
merge*
includes
set_union
set_intersection
set_difference
heap*
min*
max*
*compare
*permutation
对算法的修改
复制到 std::ranges 下
⽀持 range 作为输⼊
返回值可能更改
典型情况,返回值成为⼀个 struct,含有两个成员:in 和 out
!57
标准的 View
all
empty
take
counted
common
reverse
!58
filter
iota
join
single
split
transform
为什么要使⽤它们?
!59
⼀个 Map–Reduce 的简单例⼦
reduce(lambda x, y: x + y,
map(lambda x: x * x, range(1, 101)))
!60
⼿⼯循环?
auto square = [](int x) { return x * x; };
int sum = 0;
for (int i = 1; i < 101; ++i) {
sum += square(i);
}
!61
transform/accumulate?
auto rng = views ::iota(1, 101);
std ::vector<int> result;
std ::transform(rng.begin(), rng.end(),
std ::back_inserter(result),
square);
int sum = std ::accumulate(
result.begin(), result.end(), 0);
!62
⼩改进
int sum = nvwa ::reduce(
std ::plus<int>(),
nvwa ::fmap(square, views ::iota(1, 101)));
!63
使⽤ view::transform
int sum = nvwa ::reduce(
std ::plus<int>(), views ::iota(1, 101) |
views ::transform(square));
!64
优化编译下的汇编输出
movl $338350, %esi
!65
不过,view 不拥有元素。
!66
Python cat
def cat(files):
for fn in files:
with open(fn) as f:
for line in f:
yield line.rstrip('n')
for line in cat(sys.argv[1:]):
print(line)
!67
join 视图
!68
1, 2, 3 4, 5, 6, 7 8, 9, 10, 11, 12, 13
join
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
Range Range Range
View
cat 的天真实现版本
auto make_line_reader = [](const char* filename) {
std ::ifstream ifs(filename);
return nvwa ::istream_line_reader(ifs);
};
for (auto && line : view ::counted(argv + 1, argc - 1) |
view ::transform(make_line_reader) |
view ::join) {
std ::cout << line << std ::endl;
}
!69
有问题吗?
!70
程序会崩溃……
!71
资源必须在外部保持存活
std ::ifstream tmp;
auto make_line_reader = [&tmp](const char* filename) {
tmp = std ::ifstream(filename);
return nvwa ::istream_line_reader(tmp);
};
for (auto && line : view ::counted(argv + 1, argc - 1) |
view ::transform(make_line_reader) |
view ::join) {
std ::cout << line << std ::endl;
}
!72
Range-v3
更多的 view:如 drop, repeat, take_while, & zip
动作 (action):如 drop, sort, & unique
数字算法的 range 化:如 accumulate
能编译 range-v3 对微软来说是件值得上新闻的事!
!73
Range-v3 代码⽰例
vector<int> vd{1, 7, 3, 6, 5, 2, 4, 8};
vector<string> vs{"one", "seven", "three", "six",
"five", "two", "four", "eight"};
auto v = ranges ::views ::zip(vd, vs);
ranges ::action ::sort(v);
for (auto i : vs) {
cout << i << endl;
}
输出:
one
two
…
!74
参考资料
!75
参考资料 – Concepts
Bjarne Stroustrup, ’The C++0x “Remove Concepts” Decision’. http://www.drdobbs.com/cpp/the-c0x-remove-concepts-
decision/218600111
Jaakko Järvi, Mat Marcus, and Jacob N. Smith, ‘Programming with C++ concepts’. https://www.sciencedirect.com/
science/article/pii/S0167642309000021
Tom Honermann, ‘Why Concepts didn’t make C++17’. http://honermann.net/blog/2016/03/06/why-concepts-didnt-
make-cxx17/
Andrew Sutton, ‘Introducing Concepts’. https://accu.org/index.php/journals/2157
Andrew Sutton, ‘Defining Concepts’. https://accu.org/index.php/journals/2198
Eric Niebler and Casey Carter, ‘Working Draft, C++ Extensions for Ranges (Ranges TS)’. http://www.open-std.org/jtc1/
sc22/wg21/docs/papers/2016/n4620.pdf
Richard Smith and James Dennett, ‘Concepts TS revisited’. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/
2017/p0587r0.pdf
Herb Sutter et al. ‘Rename concepts to standard_case for C++20, while we still can’. http://www.open-std.org/jtc1/
sc22/wg21/docs/papers/2019/p1754r0.pdf
我的⽰例代码:https://github.com/adah1972/cpp_summit_2017
!76
参考资料 – Ranges
Eric Niebler, ‘D4128: Ranges for the Standard Library: Revision 1’, https://ericniebler.github.io/std/
wg21/D4128.html
Eric Niebler, ‘Range-v3’, https://ericniebler.github.io/range-v3/
Eric Niebler and Casey Carter, ‘Working Draft, C++ Extensions for Ranges’, http://www.open-std.org/
jtc1/sc22/wg21/docs/papers/2017/n4685.pdf
Eric Niebler, Casey Carter, and Christopher Di Bella, ‘The One Ranges Proposal’, http://www.open-
std.org/jtc1/sc22/wg21/docs/papers/2018/p0896r2.pdf
Casey Carter, ‘Use the official range-v3 with MSVC 2017 version 15.9’, https://
blogs.msdn.microsoft.com/vcblog/2018/11/07/use-the-official-range-v3-with-msvc-2017-version-15-9/
Ivan Čukić, Functional Programming in C++, Manning, 2019, https://www.manning.com/books/
functional-programming-in-c-plus-plus
我的⽰例代码:https://github.com/adah1972/geek_time_cpp/tree/master/29
!77

More Related Content

Similar to C++20 新功能:Concepts & Ranges

Shibuya.abc - Gnashで遊ぼう
Shibuya.abc - Gnashで遊ぼうShibuya.abc - Gnashで遊ぼう
Shibuya.abc - Gnashで遊ぼうgyuque
 
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary	[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary EnlightenmentProject
 
技術トレンディセミナー フレームワークとしてのTrac
技術トレンディセミナー フレームワークとしてのTrac技術トレンディセミナー フレームワークとしてのTrac
技術トレンディセミナー フレームワークとしてのTracterada
 
Bai Giang 11
Bai Giang 11Bai Giang 11
Bai Giang 11nbb3i
 
【12-B-4】 並列処理開発を支援するコンパイラの機能
【12-B-4】 並列処理開発を支援するコンパイラの機能【12-B-4】 並列処理開発を支援するコンパイラの機能
【12-B-4】 並列処理開発を支援するコンパイラの機能devsumi2009
 
資料庫期末Project Proposal
資料庫期末Project Proposal資料庫期末Project Proposal
資料庫期末Project ProposalFrank Chang
 
Ly Thuyet Va Bai Tap Excel
Ly Thuyet Va Bai Tap ExcelLy Thuyet Va Bai Tap Excel
Ly Thuyet Va Bai Tap Exceltrungtinh
 
とちぎRuby会議01(原)
とちぎRuby会議01(原)とちぎRuby会議01(原)
とちぎRuby会議01(原)Shin-ichiro HARA
 
Ruby on Rails 2.1 What's New Chinese Version
Ruby on Rails 2.1 What's New Chinese VersionRuby on Rails 2.1 What's New Chinese Version
Ruby on Rails 2.1 What's New Chinese VersionLibin Pan
 
樽家昌也 (日本Rubyの会)
樽家昌也 (日本Rubyの会) 樽家昌也 (日本Rubyの会)
樽家昌也 (日本Rubyの会) toRuby
 
JSplash - Adobe MAX 2009
JSplash - Adobe MAX 2009JSplash - Adobe MAX 2009
JSplash - Adobe MAX 2009gyuque
 
1242361147my upload ${file.name}
1242361147my upload ${file.name}1242361147my upload ${file.name}
1242361147my upload ${file.name}51 lecture
 
C Programming Interview Questions
C Programming Interview QuestionsC Programming Interview Questions
C Programming Interview QuestionsGradeup
 
A3 sec -_regular_expressions
A3 sec -_regular_expressionsA3 sec -_regular_expressions
A3 sec -_regular_expressionsa3sec
 

Similar to C++20 新功能:Concepts & Ranges (20)

Shibuya.abc - Gnashで遊ぼう
Shibuya.abc - Gnashで遊ぼうShibuya.abc - Gnashで遊ぼう
Shibuya.abc - Gnashで遊ぼう
 
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary	[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary
[E-Dev-Day 2014][5/16] C++ and JavaScript bindings for EFL and Elementary
 
What Can Compilers Do for Us?
What Can Compilers Do for Us?What Can Compilers Do for Us?
What Can Compilers Do for Us?
 
技術トレンディセミナー フレームワークとしてのTrac
技術トレンディセミナー フレームワークとしてのTrac技術トレンディセミナー フレームワークとしてのTrac
技術トレンディセミナー フレームワークとしてのTrac
 
Bai Giang 11
Bai Giang 11Bai Giang 11
Bai Giang 11
 
【12-B-4】 並列処理開発を支援するコンパイラの機能
【12-B-4】 並列処理開発を支援するコンパイラの機能【12-B-4】 並列処理開発を支援するコンパイラの機能
【12-B-4】 並列処理開発を支援するコンパイラの機能
 
資料庫期末Project Proposal
資料庫期末Project Proposal資料庫期末Project Proposal
資料庫期末Project Proposal
 
901131 examples
901131 examples901131 examples
901131 examples
 
20071113 Msu Vasenin Seminar
20071113 Msu Vasenin Seminar20071113 Msu Vasenin Seminar
20071113 Msu Vasenin Seminar
 
Ly Thuyet Va Bai Tap Excel
Ly Thuyet Va Bai Tap ExcelLy Thuyet Va Bai Tap Excel
Ly Thuyet Va Bai Tap Excel
 
とちぎRuby会議01(原)
とちぎRuby会議01(原)とちぎRuby会議01(原)
とちぎRuby会議01(原)
 
Ruby on Rails 2.1 What's New Chinese Version
Ruby on Rails 2.1 What's New Chinese VersionRuby on Rails 2.1 What's New Chinese Version
Ruby on Rails 2.1 What's New Chinese Version
 
樽家昌也 (日本Rubyの会)
樽家昌也 (日本Rubyの会) 樽家昌也 (日本Rubyの会)
樽家昌也 (日本Rubyの会)
 
JSplash - Adobe MAX 2009
JSplash - Adobe MAX 2009JSplash - Adobe MAX 2009
JSplash - Adobe MAX 2009
 
1242361147my upload ${file.name}
1242361147my upload ${file.name}1242361147my upload ${file.name}
1242361147my upload ${file.name}
 
Iir 08 ver.1.0
Iir 08 ver.1.0Iir 08 ver.1.0
Iir 08 ver.1.0
 
C Programming Interview Questions
C Programming Interview QuestionsC Programming Interview Questions
C Programming Interview Questions
 
Test Automation Day 2018
Test Automation Day 2018Test Automation Day 2018
Test Automation Day 2018
 
Reloaded
ReloadedReloaded
Reloaded
 
A3 sec -_regular_expressions
A3 sec -_regular_expressionsA3 sec -_regular_expressions
A3 sec -_regular_expressions
 

Recently uploaded

The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantAxelRicardoTrocheRiq
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 

Recently uploaded (20)

The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Salesforce Certified Field Service Consultant
Salesforce Certified Field Service ConsultantSalesforce Certified Field Service Consultant
Salesforce Certified Field Service Consultant
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 

C++20 新功能:Concepts & Ranges

  • 1. C++20 新功能:
 Concepts & Ranges 吴咏炜 wuyongwei@gmail.com 2020
  • 4. ⼀个例⼦ !4 template <typename N> bool odd(N n) { return bool(n & 0x1); } template <Integer N> bool odd(N n) { return bool(n & 0x1); }
  • 5. 等价形式 !5 bool odd(Integer auto n) { return bool(n & 0x1); } template <typename N> bool odd(N n) requires(Integer<N>) { return bool(n & 0x1); } 

  • 6. 为什么需要 Concepts? To make requirement on types used as template arguments explicit Precise documentation Better error messages Overloading !6
  • 7. C++11 之前的标准化努⼒ Bjarne Stroustrup and Gabriel Dos Reis: Concepts — Design choices for template argument checking. October 2003. An early discussion of design criteria for "concepts" for C++. Bjarne Stroustrup: Concept checking — A more abstract complement to type checking. October 2003. A discussion of models of "concept" checking. Bjarne Stroustrup and Gabriel Dos Reis: A concept design (Rev. 1). April 2005. An attempt to synthesize a "concept" design based on (among other sources) N1510, N1522, and N1536. Jeremy Siek, Douglas Gregor, Ronald Garcia, Jeremiah Willcock, Jaakko Jarvi, and Andrew Lumsdaine: Concepts for C++0x. N1758==05-0018. May 2005. Gabriel Dos Reis and Bjarne Stroustrup: Specifying C++ Concepts. POPL06. January 2006. D. Gregor, B. Stroustrup: Concepts. N2042==06-0012. June 2006. The basis for all further "concepts" work for C++0x. Douglas Gregor, Jaakko Jarvi, Jeremy Siek, Bjarne Stroustrup, Gabriel Dos Reis, Andrew Lumsdaine: Concepts: Linguistic Support for Generic Programming in C++. OOPSLA'06, October 2006. An academic paper on the C++0x design and its experimental compiler "ConceptGCC." Pre-Frankfurt working paper (with "concepts" in the language and standard library): http://www.open-std.org/jtc1/sc22/wg21/ docs/papers/2009/n2914.pdf . N2914=09-0104. June 2009. B. Stroustrup: Simplifying the use of concepts. N2906=09-0096. June 2009. !7
  • 8. Concepts 没有进⼊ C++11 的原因 草案复杂 Concepts Concept maps Axioms 争议颇多 没有成熟实现 !8
  • 9. Bjarne 对于 Concepts 的原则(2009) 鸭⼦类型 泛型编程模板成功的关键 不像⾯向对象⼀样需要明确使⽤接⼜ 替换性 不会匹配/调⽤⽐“保证”的先决条件要求更⾼的函数 “意外匹配”是个⼩问题 不会是 C++ 的前 100 个问题 !9
  • 11. Concepts 没有进⼊ C++17 的原因 从 Concept TS 出版到标准定稿只有不到四个⽉的时间 概念只有⼀个实现(GCC) Concept TS 规格书的作者和 GCC 中的概念实现者是同⼀个⼈;没 有⼈独⽴地从规格书出发实现概念 只有 Ranges TS 及其实现 cmcstl2 ⼤量使⽤了概念 Concept TS ⾥没有实际定义概念(Ranges TS ⾥有) !11
  • 12. (2017/7) Concept TS merged into C++20 draft !12
  • 15. CMCSTL2 ⾥的部分实际概念定义 I template <class T, class U> concept WeaklyEqualityComparable = requires(const remove_reference_t<T>& t, const remove_reference_t<U>& u) { { t == u } -> boolean; { t != u } -> boolean; { u == t } -> boolean; { u != t } -> boolean; }; 
 template <class T> concept equality_comparable = WeaklyEqualityComparable<T, T>; !15
  • 16. CMCSTL2 ⾥的部分实际概念定义 II template <class T> concept copyable = copy_constructible<T> && movable<T> && assignable_from<T&, const T&>; 
 template <class T> concept semiregular = copyable<T> && default_initializable<T>; template <class T> concept regular = semiregular<T> && equality_comparable<T>; !16
  • 17. CMCSTL2 ⾥的部分实际概念定义 III template <class I> concept weakly_incrementable = semiregular<I> && requires(I i) { typename iter_difference_t<I>; requires signed_integral<iter_difference_t<I >>; { ++i } -> same_as<I&>; i ++; }; 
 template <class I> concept input_or_output_iterator = __dereferenceable<I&> && weakly_incrementable<I>; 
 template <class I, class T> concept output_iterator = input_or_output_iterator<I> && writable<I, T> && requires(I& i, T && t) { *i ++ = std ::forward<T>(t); }; !17
  • 18. Concepts 测试 #define TEST_CONCEPT(Concept, Type ...) cout << #Concept << '<' << #Type << " >: " << Concept<Type> << endl
 TEST_CONCEPT(semiregular, std ::unique_ptr<int>); TEST_CONCEPT(equality_comparable, std ::unique_ptr<int>); TEST_CONCEPT(readable, int); TEST_CONCEPT(readable, std ::unique_ptr<int>); TEST_CONCEPT(writable, std ::unique_ptr<int>, int); TEST_CONCEPT(semiregular, arma ::imat); TEST_CONCEPT(assignable_from, arma ::imat&, arma ::imat&); TEST_CONCEPT(semiregular, arma ::imat22); TEST_CONCEPT(assignable_from, arma ::imat22&, arma ::imat22&); TEST_CONCEPT(regular, int); TEST_CONCEPT(regular, char); TEST_CONCEPT(integral, int); TEST_CONCEPT(integral, char); !18
  • 19. Concepts 测试结果 semiregular<std::unique_ptr<int>>: false equality_comparable<std::unique_ptr<int>>: true readable<int>: false readable<std::unique_ptr<int>>: true writable<std::unique_ptr<int>, int>: true semiregular<arma::imat>: true assignable_from<arma::imat&, arma::imat&>: true semiregular<arma::imat22>: false assignable_from<arma::imat22&, arma::imat22&>: false regular<int>: true regular<char>: true integral<int>: true integral<char>: true !19
  • 20. Sutton 的例⼦ template <typename R, typename T> bool in(R const& r, T const& value) requires range<R> && equality_comparable_with<T, typename R ::value_type> { for (auto const& x : r) if (x == value) return true; return false; } vector<string> v{"Hello", "World"}; in(v, 0); !20
  • 21. 出错信息 GCC 8.3 缺省输出 166 ⾏ Clang 9.0 缺省输出 82 ⾏ GCC 8.3 -std=c++17 -fconcepts 输出 sutton_example.cpp: In function 'int main()': sutton_example.cpp:26:12: error: cannot call function 'bool in(const R&, const T&) requires range<R> and equality_comparable_with<T, typename R::value_type> [with R = std::vector<std::__cxx11::basic_string<char> >; T = int]' in(v, 0); ^ sutton_example.cpp:13:6: note: constraints not satisfied bool in(R const& range_, T const& value) ^~ sutton_example.cpp:13:6: note: in the expansion of concept 'equality_comparable_with<T, typename R::value_type> template<class T, class U> concept const bool std::experimental::ranges::v1::equality_comparable_with<T, U> [with T = int; U = std::vector<std::__cxx11::basic_string<char> >::value_type]' !21
  • 22. 概念和重载 template <typename R> bool in(R const& r, size_t value) requires requires(R r) { r.size(); } { if (r.size() == value) return true; return false; } vector<string> v{"Hello", "World"}; in(v, "Hello"); in(v, 0); !22
  • 23. 不使⽤ Concept 时的变通重载⽅法 template <typename _Fn, typename _T1, typename _T2> constexpr auto fmap(_Fn && f, const std ::pair<_T1, _T2>& args); template <typename _Fn, typename ... _Targs> constexpr auto fmap(_Fn && f, const std ::tuple<_Targs ...>& args); template <template <typename, typename> class _OutCont = std ::vector, template <typename> class _Alloc = std ::allocator, typename _Fn, class _Rng> constexpr auto fmap(_Fn && f, _Rng && inputs) -> decltype( begin(inputs), end(inputs), _OutCont< std ::decay_t<decltype(f(*begin(inputs)))>, _Alloc<std ::decay_t<decltype(f(*begin(inputs))) >>>()); !23
  • 24. 另⼀个 SFINAE template <class _T1, class _T2> struct can_reserve { struct good { char dummy; }; struct bad { char dummy[2]; }; template <class _Up, void (_Up ::*)(size_t)> struct _SFINAE1 {}; template <class _Up, size_t (_Up ::*)() const> struct _SFINAE2 {}; template <class _Up> static good reserve(_SFINAE1<_Up, &_Up ::reserve>*); template <class _Up> static bad reserve( ...); template <class _Up> static good size(_SFINAE2<_Up, &_Up ::size>*); template <class _Up> static bad size( ...); static const bool value = (sizeof(reserve<_T1>(nullptr)) == sizeof(good) && sizeof(size<_T2>(nullptr)) == sizeof(good)); }; 
 template <class _T1, class _T2> void try_reserve(_T1&, const _T2&, std ::false_type) {} template <class _T1, class _T2> void try_reserve(_T1& dest, const _T2& src, std ::true_type) { dest.reserve(src.size()); } 
 try_reserve(result, inputs, std ::integral_constant<bool, can_reserve<decltype(result), _Rng> ::value>()); !24
  • 25. ⽤ Concept 进⾏简化 template <typename _T1, typename _T2> concept can_reserve = requires(_T1& dest, const _T2& src) { dest.reserve(src.size()); }; 
 template <class _T1, class _T2> void try_reserve(_T1&, const _T2&, std ::false_type) {} template <class _T1, class _T2> void try_reserve(_T1& dest, const _T2& src, std ::true_type) { dest.reserve(src.size()); }
 try_reserve(result, inputs, std ::integral_constant<bool, can_reserve<decltype(result), _Rng >>()); !25
  • 26. ⽤ if constexpr 进⼀步简化 template <typename _T1, typename _T2> concept can_reserve = requires(_T1& dest, const _T2& src) { dest.reserve(src.size()); }; if constexpr (can_reserve<decltype(result), _Rng>) { result.reserve(inputs.size()); } !26
  • 27. 使⽤ Concepts 的问题 样例实现尚未跟上 Concepts 的标准 如代码中的“concept”在 GCC(到 9 为⽌)需要写“concept bool” 特定概念的定义和名称有⼩概率可能变化 CMCSTL2 已经跟随标准草稿进⾏了⼀次⼤规模更新 使⽤概念后能⼯作的代码可能会停⽌⼯作 如果对象使⽤了特殊技巧,不 regular 的话 概念的出错提⽰友好性部分被 -Wfatal-errors 抵消 !27
  • 30. ⼀点历史 Boost.Range, 2003 D range, ~2009 Range-v3, 2013 Ranges TS, 2017 合并进 C++20, 2018 正式标准化, ~2020 !30
  • 31. Ranges 之前的代码 int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; std ::sort(std ::begin(a), std ::end(a)); std ::copy(std ::begin(a), std ::end(a), std ::ostream_iterator<int>( std ::cout, " ")); !31
  • 32. Ranges ⽰例——排序 namespace ranges = std ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; ranges ::sort(a); ranges ::copy(a, ranges ::ostream_iterator<int>( std ::cout, " ")); !32
  • 33. Ranges ⽰例——反向视图 namespace ranges = std ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::reverse_view(a); ranges ::copy(r, ranges ::ostream_iterator<int>( std ::cout, " ")); !33
  • 34. Ranges ⽰例——过滤视图 namespace ranges = std ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::filter_view(a, [](int i) { return i % 2 == 0; }); ranges ::copy(r, ranges ::ostream_iterator<int>( std ::cout, " ")); !34
  • 35. Ranges ⽰例——级联视图 namespace ranges = std ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = ranges ::reverse_view( ranges ::filter_view(a, [](int i) { return i % 2 == 0; })); ranges ::copy(r, ranges ::ostream_iterator<int>( std ::cout, " ")); !35
  • 36. Ranges ⽰例——管道 namespace ranges = std ::ranges; int a[] = {1, 7, 3, 6, 5, 2, 4, 8}; auto r = a | ranges ::view ::filter( [](int i) { return i % 2 == 0; }) | ranges ::view ::reverse; ranges ::copy(r, ranges ::ostream_iterator<int>( std ::cout, " ")); !36
  • 37. 想象 Unix 管道 do_something … | grep … | sort | uniq !37
  • 39. Range 的定义 template <class T> concept _RangeImpl = requires(T && t) { ranges ::begin(static_cast<T &&>(t)); ranges ::end(static_cast<T &&>(t)); }; template<class T> concept range = _RangeImpl<T&>; !39
  • 40. Range 相关的概念 input_range common_range forward_range bidirectional_range random_access_range output_range sized_range contiguous_range view range !40 semiregular copyable default_initializable
  • 41. view template <class T> concept view = range<T> && semiregular<T> && enable_view< __uncvref<T >>; !41
  • 42. common_range template <class T> concept common_range = range<T> && same_as<iterator_t<T>, sentinel_t<T >>; !42
  • 43. sized_range template <class T> concept sized_range = range<T> && requires(T& r) { size(r); }; !43
  • 44. output_range template <class R, class T> concept output_range = range<R> && output_iterator<iterator_t<R>, T>; !44
  • 45. input_range template <class T> concept input_range = range<T> && input_iterator<iterator_t<T >>; !45
  • 46. Sentinel 例⼦ struct null_sentinel {}; template <input_or_output_iterator I> bool operator !=(I i, null_sentinel) { return *i != 0; } //template <Iterator I> //operator !=(null_sentinel, I i), operator ==, …
 ranges ::for_each(argv[1], null_sentinel(), [](char ch) { std ::cout << ch; }); !46
  • 47. 视图(View) 不(唯⼀)拥有元素(允许和其他 view 共同拥有) 常数时间拷贝、移动或赋值 ⼤多数容器是 range,不是 view C++17 string_view 满⾜ view 的条件,但 string 不满⾜ View 满⾜ semiregular,即 copyable 和 default_initializable !47
  • 48. Range 概念检查 I !48 vector<int> const vector<int> range ✓ ✓ view ✗ ✗ sized_range ✓ ✓ common_range ✓ ✓ output_range ✓ ✗ input_range ✓ ✓ forward_range ✓ ✓ bidirectional_range ✓ ✓ random_access_range ✓ ✓ contiguous_range ✓ ✓
  • 49. Range 概念检查 II !49 list<int> const list<int> range ✓ ✓ view ✗ ✗ sized_range ✓ ✓ common_range ✓ ✓ output_range ✓ ✗ input_range ✓ ✓ forward_range ✓ ✓ bidirectional_range ✓ ✓ random_access_range ✗ ✗ contiguous_range ✗ ✗
  • 50. Range 概念检查 III !50 int [8] int const [8] range ✓ ✓ view ✗ ✗ sized_range ✓ ✓ common_range ✓ ✓ output_range ✓ ✗ input_range ✓ ✓ forward_range ✓ ✓ bidirectional_range ✓ ✓ random_access_range ✓ ✓ contiguous_range ✓ ✓
  • 51. Range 概念检查 IV !51 reverse_view<int [8]> reverse_view<int const [8]> range ✓ ✓ view ✓ ✓ sized_range ✓ ✓ common_range ✓ ✓ output_range ✓ ✗ input_range ✓ ✓ forward_range ✓ ✓ bidirectional_range ✓ ✓ random_access_range ✓ ✓ contiguous_range ✗ ✗
  • 52. Range 概念检查 V !52 filter_view<int [8]> filter_view<int const [8]> range ✓ ✓ view ✓ ✓ sized_range ✗ ✗ common_range ✓ ✓ output_range ✓ ✗ input_range ✓ ✓ forward_range ✓ ✓ bidirectional_range ✓ ✓ random_access_range ✗ ✗ contiguous_range ✗ ✗
  • 53. Range 概念检查 VI !53 istream_line_reader take_view<istream_line_reader> range ✓ ✓ view ✓ ✓ sized_range ✗ ✗ common_range ✓ ✗ output_range ✗ ✗ input_range ✓ ✓ forward_range ✗ ✗ bidirectional_range ✗ ✗ random_access_range ✗ ✗ contiguous_range ✗ ✗
  • 54. Range 概念检查 VII !54 iota_view(0) iota_view(0, 5) iota_view(0) | take(5) range ✓ ✓ ✓ view ✓ ✓ ✓ sized_range ✗ ✓ ✗ common_range ✗ ✓ ✗ output_range ✗ ✗ ✗ input_range ✓ ✓ ✓ forward_range ✓ ✓ ✓ bidirectional_range ✓ ✓ ✓ random_access_range ✓ ✓ ✓ contiguous_range ✗ ✗ ✗
  • 55. 并⼊ C++20 的 Range 基于 D4128, Range-v3 和 Range TS 分离名空间来减少影响 std::ranges (之前是 std::experimental::ranges) 但基本概念仍然放在 std 名空间⾥ 定义了很多概念 (concepts) 添加了视图 (views) 和视图适配器 (view adapters) 修改了标准算法 (algorithms)和⼯具 (utilities) !55
  • 57. 对算法的修改 复制到 std::ranges 下 ⽀持 range 作为输⼊ 返回值可能更改 典型情况,返回值成为⼀个 struct,含有两个成员:in 和 out !57
  • 60. ⼀个 Map–Reduce 的简单例⼦ reduce(lambda x, y: x + y, map(lambda x: x * x, range(1, 101))) !60
  • 61. ⼿⼯循环? auto square = [](int x) { return x * x; }; int sum = 0; for (int i = 1; i < 101; ++i) { sum += square(i); } !61
  • 62. transform/accumulate? auto rng = views ::iota(1, 101); std ::vector<int> result; std ::transform(rng.begin(), rng.end(), std ::back_inserter(result), square); int sum = std ::accumulate( result.begin(), result.end(), 0); !62
  • 63. ⼩改进 int sum = nvwa ::reduce( std ::plus<int>(), nvwa ::fmap(square, views ::iota(1, 101))); !63
  • 64. 使⽤ view::transform int sum = nvwa ::reduce( std ::plus<int>(), views ::iota(1, 101) | views ::transform(square)); !64
  • 67. Python cat def cat(files): for fn in files: with open(fn) as f: for line in f: yield line.rstrip('n') for line in cat(sys.argv[1:]): print(line) !67
  • 68. join 视图 !68 1, 2, 3 4, 5, 6, 7 8, 9, 10, 11, 12, 13 join 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 Range Range Range View
  • 69. cat 的天真实现版本 auto make_line_reader = [](const char* filename) { std ::ifstream ifs(filename); return nvwa ::istream_line_reader(ifs); }; for (auto && line : view ::counted(argv + 1, argc - 1) | view ::transform(make_line_reader) | view ::join) { std ::cout << line << std ::endl; } !69
  • 72. 资源必须在外部保持存活 std ::ifstream tmp; auto make_line_reader = [&tmp](const char* filename) { tmp = std ::ifstream(filename); return nvwa ::istream_line_reader(tmp); }; for (auto && line : view ::counted(argv + 1, argc - 1) | view ::transform(make_line_reader) | view ::join) { std ::cout << line << std ::endl; } !72
  • 73. Range-v3 更多的 view:如 drop, repeat, take_while, & zip 动作 (action):如 drop, sort, & unique 数字算法的 range 化:如 accumulate 能编译 range-v3 对微软来说是件值得上新闻的事! !73
  • 74. Range-v3 代码⽰例 vector<int> vd{1, 7, 3, 6, 5, 2, 4, 8}; vector<string> vs{"one", "seven", "three", "six", "five", "two", "four", "eight"}; auto v = ranges ::views ::zip(vd, vs); ranges ::action ::sort(v); for (auto i : vs) { cout << i << endl; } 输出: one two … !74
  • 76. 参考资料 – Concepts Bjarne Stroustrup, ’The C++0x “Remove Concepts” Decision’. http://www.drdobbs.com/cpp/the-c0x-remove-concepts- decision/218600111 Jaakko Järvi, Mat Marcus, and Jacob N. Smith, ‘Programming with C++ concepts’. https://www.sciencedirect.com/ science/article/pii/S0167642309000021 Tom Honermann, ‘Why Concepts didn’t make C++17’. http://honermann.net/blog/2016/03/06/why-concepts-didnt- make-cxx17/ Andrew Sutton, ‘Introducing Concepts’. https://accu.org/index.php/journals/2157 Andrew Sutton, ‘Defining Concepts’. https://accu.org/index.php/journals/2198 Eric Niebler and Casey Carter, ‘Working Draft, C++ Extensions for Ranges (Ranges TS)’. http://www.open-std.org/jtc1/ sc22/wg21/docs/papers/2016/n4620.pdf Richard Smith and James Dennett, ‘Concepts TS revisited’. http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ 2017/p0587r0.pdf Herb Sutter et al. ‘Rename concepts to standard_case for C++20, while we still can’. http://www.open-std.org/jtc1/ sc22/wg21/docs/papers/2019/p1754r0.pdf 我的⽰例代码:https://github.com/adah1972/cpp_summit_2017 !76
  • 77. 参考资料 – Ranges Eric Niebler, ‘D4128: Ranges for the Standard Library: Revision 1’, https://ericniebler.github.io/std/ wg21/D4128.html Eric Niebler, ‘Range-v3’, https://ericniebler.github.io/range-v3/ Eric Niebler and Casey Carter, ‘Working Draft, C++ Extensions for Ranges’, http://www.open-std.org/ jtc1/sc22/wg21/docs/papers/2017/n4685.pdf Eric Niebler, Casey Carter, and Christopher Di Bella, ‘The One Ranges Proposal’, http://www.open- std.org/jtc1/sc22/wg21/docs/papers/2018/p0896r2.pdf Casey Carter, ‘Use the official range-v3 with MSVC 2017 version 15.9’, https:// blogs.msdn.microsoft.com/vcblog/2018/11/07/use-the-official-range-v3-with-msvc-2017-version-15-9/ Ivan Čukić, Functional Programming in C++, Manning, 2019, https://www.manning.com/books/ functional-programming-in-c-plus-plus 我的⽰例代码:https://github.com/adah1972/geek_time_cpp/tree/master/29 !77