Skip to content

Commit f913f21

Browse files
committed
P0433R2 Integrating template deduction for class templates into the standard library
Deduction guides for lock_guard and scoped_lock are not in this branch, but in motions-2017-03-lwg-17 instead (with the changes to lock_guard and scoped_lock). Editorial differences from P0433R2 wording: - Consistent indentation and whitespace. - [namespace.std] Replace period of previous \item with ", or". - [allocator.adaptor.syn] Fix "OuterAllocator" parameter, to "OuterAlloc". - [refwrap] Change "typename T" to "class T" in template parameter list. - [sequence.reqmts] Add period after "unevaluated operand" and parentheses around cross-reference to [temp.deduct]. - [associative.reqmts] Add periods after each \item. - [unord.reqmts] Add periods after each \item. - [associative.overview] Change "exposition only type aliases" to "exposition-only alias templates" and add semi-colon after third template. - [unord.general] Change "exposition only type aliases" to "exposition-only alias templates". - [template.valarray.overview] Change "typename T" to "class T". - [container.adaptors.general] Added periods to bullet list items. - [thread.lock.unique]. [thread.lock.shared] Change parameter M to Mutex. Also fixes NB US-7, US-14 (C++17 CD)
1 parent 49caa2b commit f913f21

File tree

7 files changed

+507
-97
lines changed

7 files changed

+507
-97
lines changed

source/containers.tex

Lines changed: 401 additions & 1 deletion
Large diffs are not rendered by default.

source/lib-intro.tex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2177,7 +2177,9 @@
21772177
standard library class or class template, or
21782178

21792179
\item an explicit or partial specialization of any member class template
2180-
of a standard library class or class template.
2180+
of a standard library class or class template, or
2181+
2182+
\item a deduction guide for any standard library class template.
21812183
\end{itemize}
21822184
A program may explicitly instantiate a template defined in the standard library
21832185
only if the declaration depends on the name of a user-defined type

source/numerics.tex

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6737,6 +6737,8 @@
67376737
valarray apply(T func(const T&)) const;
67386738
void resize(size_t sz, T c = T());
67396739
};
6740+
6741+
template<class T, size_t cnt> valarray(const T(&)[cnt], size_t) -> valarray<T>;
67406742
}
67416743
\end{codeblock}
67426744

source/regex.tex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,11 @@
14071407
// \ref{re.regex.swap}, swap
14081408
void swap(basic_regex&);
14091409
};
1410+
1411+
template<class ForwardIterator>
1412+
basic_regex(ForwardIterator, ForwardIterator,
1413+
regex_constants::syntax_option_type = regex_constants::ECMAScript)
1414+
-> basic_regex<typename iterator_traits<ForwardIterator>::value_type>;
14101415
}
14111416
\end{codeblock}
14121417

source/strings.tex

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1134,6 +1134,13 @@
11341134
int compare(size_type pos1, size_type n1,
11351135
const charT* s, size_type n2) const;
11361136
};
1137+
1138+
template<class InputIterator,
1139+
class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1140+
basic_string(InputIterator, InputIterator, Allocator = Allocator())
1141+
-> basic_string<typename iterator_traits<InputIterator>::value_type,
1142+
char_traits<typename iterator_traits<InputIterator>::value_type>,
1143+
Allocator>;
11371144
}
11381145
\end{codeblock}
11391146

@@ -1472,6 +1479,20 @@
14721479
\throws The second form throws nothing if \tcode{alloc == str.get_allocator()}.
14731480
\end{itemdescr}
14741481

1482+
\begin{itemdecl}
1483+
template<class InputIterator,
1484+
class Allocator = allocator<typename iterator_traits<InputIterator>::value_type>>
1485+
basic_string(InputIterator, InputIterator, Allocator = Allocator())
1486+
-> basic_string<typename iterator_traits<InputIterator>::value_type,
1487+
char_traits<typename iterator_traits<InputIterator>::value_type>,
1488+
Allocator>;
1489+
\end{itemdecl}
1490+
1491+
\begin{itemdescr}
1492+
\remarks Shall not participate in overload resolution if
1493+
\tcode{InputIterator} is a type that does not qualify as an input iterator,
1494+
or if \tcode{Allocator} is a type that does not qualify as an allocator~(\ref{sequence.reqmts}).
1495+
\end{itemdescr}
14751496

14761497
\indexlibrarymember{operator=}{basic_string}%
14771498
\begin{itemdecl}

source/threads.tex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,8 @@
17711771
bool owns; // \expos
17721772
};
17731773

1774+
template<class Mutex> unique_lock(unique_lock<Mutex>) -> unique_lock<Mutex>;
1775+
17741776
template <class Mutex>
17751777
void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept;
17761778
}
@@ -2214,6 +2216,8 @@
22142216
bool owns; // \expos
22152217
};
22162218

2219+
template<class Mutex> shared_lock(shared_lock<Mutex>) -> shared_lock<Mutex>;
2220+
22172221
template <class Mutex>
22182222
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;
22192223
}

source/utilities.tex

Lines changed: 71 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -905,6 +905,9 @@
905905

906906
void swap(pair& p) noexcept(@\seebelow@);
907907
};
908+
909+
template<class T1, class T2>
910+
pair(T1, T2) -> pair<T1, T2>;
908911
}
909912
\end{codeblock}
910913

@@ -1542,6 +1545,17 @@
15421545
// \ref{tuple.swap}, \tcode{tuple} swap
15431546
void swap(tuple&) noexcept(@\seebelow@);
15441547
};
1548+
1549+
template<class... UTypes>
1550+
tuple(UTypes...) -> tuple<UTypes...>;
1551+
template<class T1, class T2>
1552+
tuple(pair<T1, T2>) -> tuple<T1, T2>;
1553+
template<class Alloc, class... UTypes>
1554+
tuple(allocator_arg_t, Alloc, UTypes...) -> tuple<UTypes...>;
1555+
template<class Alloc, class T1, class T2>
1556+
tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;
1557+
template<class Alloc, class... UTypes>
1558+
tuple(allocator_arg_t, Alloc, tuple<UTypes...>) -> tuple<UTypes...>;
15451559
}
15461560
\end{codeblock}
15471561

@@ -2632,6 +2646,8 @@
26322646
private:
26332647
T *val; // \expos
26342648
};
2649+
2650+
template<class T> optional(T) -> optional<T>;
26352651
\end{codeblock}
26362652

26372653
\pnum
@@ -8485,6 +8501,9 @@
84858501
\pnum
84868502
\remarks If this constructor is instantiated with a pointer type or reference type
84878503
for the template argument \tcode{D}, the program is ill-formed.
8504+
If class template argument deduction~(\ref{over.match.class.deduct})
8505+
would select the function template corresponding to this constructor,
8506+
then the program is ill-formed.
84888507
\end{itemdescr}
84898508

84908509
\indexlibrary{\idxcode{unique_ptr}!constructor}%
@@ -8570,6 +8589,10 @@
85708589
deleter. If \tcode{D} is a reference type then \tcode{get_deleter()}
85718590
returns a reference to the lvalue \tcode{d}.
85728591

8592+
\remarks If class template argument deduction~(\ref{over.match.class.deduct})
8593+
would select a function template corresponding to either of these constructors,
8594+
then the program is ill-formed.
8595+
85738596
\begin{example}
85748597

85758598
\begin{codeblock}
@@ -9397,6 +9420,9 @@
93979420
template<class U> bool owner_before(const weak_ptr<U>& b) const;
93989421
};
93999422

9423+
template<class T> shared_ptr(weak_ptr<T>) -> shared_ptr<T>;
9424+
template<class T, class D> shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>;
9425+
94009426
// \ref{util.smartptr.shared.create}, \tcode{shared_ptr} creation
94019427
template<class T, class... Args>
94029428
shared_ptr<T> make_shared(Args&&... args);
@@ -10312,6 +10338,9 @@
1031210338
template<class U> bool owner_before(const weak_ptr<U>& b) const;
1031310339
};
1031410340

10341+
template<class T> weak_ptr(shared_ptr<T>) -> weak_ptr<T>;
10342+
10343+
1031510344
// \ref{util.smartptr.weak.spec}, specialized algorithms
1031610345
template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
1031710346
}
@@ -12208,6 +12237,10 @@
1220812237
scoped_allocator_adaptor select_on_container_copy_construction() const;
1220912238
};
1221012239

12240+
template<class OuterAlloc, class... InnerAllocs>
12241+
scoped_allocator_adaptor(OuterAlloc, InnerAllocs...)
12242+
-> scoped_allocator_adaptor<OuterAlloc, InnerAllocs...>;
12243+
1221112244
template <class OuterA1, class OuterA2, class... InnerAllocs>
1221212245
bool operator==(const scoped_allocator_adaptor<OuterA1, InnerAllocs...>& a,
1221312246
const scoped_allocator_adaptor<OuterA2, InnerAllocs...>& b) noexcept;
@@ -12831,33 +12864,6 @@
1283112864
class BinaryPredicate = equal_to<>>
1283212865
class boyer_moore_horspool_searcher;
1283312866

12834-
template<class ForwardIterator, class BinaryPredicate = equal_to<>>
12835-
default_searcher<ForwardIterator, BinaryPredicate>
12836-
make_default_searcher(
12837-
ForwardIterator pat_first,
12838-
ForwardIterator pat_last,
12839-
BinaryPredicate pred = BinaryPredicate());
12840-
12841-
template<class RandomAccessIterator,
12842-
class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
12843-
class BinaryPredicate = equal_to<>>
12844-
boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
12845-
make_boyer_moore_searcher(
12846-
RandomAccessIterator pat_first,
12847-
RandomAccessIterator pat_last,
12848-
Hash hf = Hash(),
12849-
BinaryPredicate pred = BinaryPredicate());
12850-
12851-
template<class RandomAccessIterator,
12852-
class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
12853-
class BinaryPredicate = equal_to<>>
12854-
boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
12855-
make_boyer_moore_horspool_searcher(
12856-
RandomAccessIterator pat_first,
12857-
RandomAccessIterator pat_last,
12858-
Hash hf = Hash(),
12859-
BinaryPredicate pred = BinaryPredicate());
12860-
1286112867
// \ref{unord.hash}, hash function primary template
1286212868
template <class T>
1286312869
struct hash;
@@ -13041,6 +13047,9 @@
1304113047
result_of_t<T&(ArgTypes&&...)>
1304213048
operator() (ArgTypes&&...) const;
1304313049
};
13050+
13051+
template<class T>
13052+
reference_wrapper(reference_wrapper<T>) -> reference_wrapper<T>;
1304413053
}
1304513054
\end{codeblock}
1304613055

@@ -14343,9 +14352,13 @@
1434314352
const type_info& target_type() const noexcept;
1434414353
template<class T> T* target() noexcept;
1434514354
template<class T> const T* target() const noexcept;
14346-
1434714355
};
1434814356

14357+
template<class R, class... ArgTypes>
14358+
function(R(*)(ArgTypes...)) -> function<R(ArgTypes...)>;
14359+
14360+
template<class F> function(F) -> function<@\seebelow@>;
14361+
1434914362
// \ref{func.wrap.func.nullptr}, Null pointer comparisons
1435014363
template <class R, class... ArgTypes>
1435114364
bool operator==(const function<R(ArgTypes...)>&, nullptr_t) noexcept;
@@ -14387,6 +14400,12 @@
1438714400
wrapper~(\ref{func.def}) whose call signature~(\ref{func.def})
1438814401
is \tcode{R(ArgTypes...)}.
1438914402

14403+
\pnum
14404+
\begin{note}
14405+
The types deduced by the deduction guides for \tcode{function}
14406+
may change in future versions of this International Standard.
14407+
\end{note}
14408+
1439014409
\rSec4[func.wrap.func.con]{\tcode{function} construct/copy/destroy}
1439114410

1439214411
\indexlibrary{\idxcode{function}!constructor}%
@@ -14491,6 +14510,30 @@
1449114510
or move constructor.
1449214511
\end{itemdescr}
1449314512

14513+
14514+
\begin{itemdecl}
14515+
template<class F> function(F) -> function<@\seebelow@>;
14516+
\end{itemdecl}
14517+
14518+
\begin{itemdescr}
14519+
\pnum
14520+
\remarks This deduction guide participates in overload resolution only if
14521+
\tcode{\&F::operator()} is well-formed when treated as an unevaluated operand.
14522+
In that case, if \tcode{decltype(\&F::operator())} is of the form
14523+
\tcode{R(G::*)(A...)}~\cv{}~\tcode{\&\opt{}~noexcept\opt}
14524+
for a class type \tcode{G}, then the deduced type is \tcode{function<R(A...)>}.
14525+
14526+
\pnum
14527+
\begin{example}
14528+
\begin{codeblock}
14529+
void f() {
14530+
int i{5};
14531+
function g = [&](double) { return i; }; // deduces \tcode{function<int(double)>}
14532+
}
14533+
\end{codeblock}
14534+
\end{example}
14535+
\end{itemdescr}
14536+
1449414537
\indexlibrarymember{operator=}{function}%
1449514538
\begin{itemdecl}
1449614539
function& operator=(const function& f);
@@ -14762,25 +14805,6 @@
1476214805
\end{itemize}
1476314806
\end{itemdescr}
1476414807

14765-
\rSec4[func.search.default.creation]{\tcode{default_searcher} creation functions}
14766-
14767-
\indexlibrary{\idxcode{make_default_searcher}}%
14768-
\begin{itemdecl}
14769-
template <class ForwardIterator, class BinaryPredicate = equal_to<>>
14770-
default_searcher<ForwardIterator, BinaryPredicate>
14771-
make_default_searcher(ForwardIterator pat_first, ForwardIterator pat_last,
14772-
BinaryPredicate pred = BinaryPredicate());
14773-
\end{itemdecl}
14774-
14775-
\begin{itemdescr}
14776-
\pnum
14777-
\effects
14778-
Equivalent to:
14779-
\begin{codeblock}
14780-
return default_searcher<ForwardIterator, BinaryPredicate>(pat_first, pat_last, pred);
14781-
\end{codeblock}
14782-
\end{itemdescr}
14783-
1478414808
\rSec3[func.search.bm]{Class template \tcode{boyer_moore_searcher}}
1478514809

1478614810
\indexlibrary{\idxcode{boyer_moore_searcher}}%
@@ -14874,30 +14898,6 @@
1487414898
At most \tcode{(last - first) * (pat_last_ - pat_first_)} applications of the predicate.
1487514899
\end{itemdescr}
1487614900

14877-
\rSec4[func.search.bm.creation]{\tcode{boyer_moore_searcher} creation functions}
14878-
14879-
\indexlibrary{\idxcode{make_boyer_moore_searcher}}%
14880-
\begin{itemdecl}
14881-
template <class RandomAccessIterator,
14882-
class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
14883-
class BinaryPredicate = equal_to<>>
14884-
boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>
14885-
make_boyer_moore_searcher(RandomAccessIterator pat_first,
14886-
RandomAccessIterator pat_last,
14887-
Hash hf = Hash(),
14888-
BinaryPredicate pred = BinaryPredicate());
14889-
\end{itemdecl}
14890-
14891-
\begin{itemdescr}
14892-
\pnum
14893-
\effects
14894-
Equivalent to:
14895-
\begin{codeblock}
14896-
return boyer_moore_searcher<RandomAccessIterator, Hash, BinaryPredicate>(
14897-
pat_first, pat_last, hf, pred);
14898-
\end{codeblock}
14899-
\end{itemdescr}
14900-
1490114901
\rSec3[func.search.bmh]{Class template \tcode{boyer_moore_horspool_searcher}}
1490214902

1490314903
\indexlibrary{\idxcode{boyer_moore_horspool_searcher}}%
@@ -14991,30 +14991,6 @@
1499114991
At most \tcode{(last - first) * (pat_last_ - pat_first_)} applications of the predicate.
1499214992
\end{itemdescr}
1499314993

14994-
\rSec4[func.search.bmh.creation]{\tcode{boyer_moore_horspool_searcher} creation functions}
14995-
14996-
\indexlibrary{\idxcode{make_boyer_moore_horspool_searcher}}%
14997-
\begin{itemdecl}
14998-
template <class RandomAccessIterator,
14999-
class Hash = hash<typename iterator_traits<RandomAccessIterator>::value_type>,
15000-
class BinaryPredicate = equal_to<>>
15001-
boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>
15002-
make_boyer_moore_horspool_searcher(RandomAccessIterator pat_first,
15003-
RandomAccessIterator pat_last,
15004-
Hash hf = Hash(),
15005-
BinaryPredicate pred = BinaryPredicate());
15006-
\end{itemdecl}
15007-
15008-
\begin{itemdescr}
15009-
\pnum
15010-
\effects
15011-
Equivalent to:
15012-
\begin{codeblock}
15013-
return boyer_moore_horspool_searcher<RandomAccessIterator, Hash, BinaryPredicate>(
15014-
pat_first, pat_last, hf, pred);
15015-
\end{codeblock}
15016-
\end{itemdescr}
15017-
1501814994
\rSec2[unord.hash]{Class template \tcode{hash}}
1501914995

1502014996
\pnum

0 commit comments

Comments
 (0)