Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
cpp-shots
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Ansgar Burchardt
cpp-shots
Commits
509fd52d
Commit
509fd52d
authored
7 years ago
by
Ansgar Burchardt
Browse files
Options
Downloads
Patches
Plain Diff
presentation: class template argument deduction
parent
779a4976
Branches
master
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
vortrag_05-31/class-template-argument-deduction.tex
+262
-0
262 additions, 0 deletions
vortrag_05-31/class-template-argument-deduction.tex
with
262 additions
and
0 deletions
vortrag_05-31/class-template-argument-deduction.tex
0 → 100644
+
262
−
0
View file @
509fd52d
\documentclass
{
beamer
}
\usepackage
{
listings
}
\lstset
{
language=C++
}
\title
{
Class Template Argument Deduction
}
\author
{
Ansgar Burchardt
}
\date
{
31 May 2017
}
\begin{document}
\begin{frame}
\maketitle
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
Motivation
}
\begin{lstlisting}
std::vector<int> xs =
{
1, 2, 3
}
;
std::array<int, 3> ys =
{
1, 2, 3
}
;
\end{lstlisting}
\pause
\begin{lstlisting}
std::pair<???, ???> p =
{
someThing(), someThingElse()
}
;
\end{lstlisting}
The
\lstinline
|???| are unspeakable.
\pause
\begin{lstlisting}
auto p = std::make
_
pair(
someThing(), someThingElse()
);
\end{lstlisting}
But writing helper functions is not nice!
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
Motivation II
}
C++17:
\begin{lstlisting}
std::vector xs =
{
1, 2, 3
}
;
std::array ys =
{
1, 2, 3
}
;
std::pair p =
{
someThing(), someThingElse()
}
;
\end{lstlisting}
Yay!
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
How does it work?
}
\begin{lstlisting}
template<typename T>
class C
{
C(T a);
}
;
auto a = C(1);
\end{lstlisting}
\pause
Consider template function
\begin{lstlisting}
template<typename T>
auto C(T a) -> C<T>;
\end{lstlisting}
calling
\lstinline
|C(1)| returns a
\lstinline
|C<int>|.
\pause
Same as:
\begin{lstlisting}
template<typename T>
C<T> C(T a);
\end{lstlisting}
\pause
This is done for all constructors.
(Automatic deduction guides.)
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
The need for user-defined deduction guides
}
\begin{lstlisting}
template<typename T>
class C
{
C(T a);
template<typename It>
C(It begin, It end);
}
;
It begin, end;
auto a = C(begin, end);
\end{lstlisting}
\pause
\begin{lstlisting}
template<typename T, typename It>
auto C(It begin, It end) -> C<T>;
\end{lstlisting}
\lstinline
|T| cannot be deduced from
\lstinline
|C(begin, end)|!
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
User-defined deduction guides
}
\begin{lstlisting}
template<typename T>
class C
{
template<typename It>
C(It begin, It end);
}
;
template<typename It>
C(It, It) -> C<typename It::value
_
type>;
\end{lstlisting}
\pause
With this we have two deduction guides:
\begin{lstlisting}
template<typename T, typename It>
C(It begin, It end) -> C<T>;
template<typename It>
C(It begin, It end) -> C<typename It::value
_
type>;
\end{lstlisting}
\begin{lstlisting}
It begin, end;
auto a = C(begin, end);
\end{lstlisting}
will use second (user-defined) one.
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
But not all is good
}
\begin{lstlisting}
template<typename K, int dim>
class Vector
{
Vector(std::initializer
_
list<K>);
}
;
\end{lstlisting}
Here
\lstinline
|dim| cannot be deduced, even with user-defined deduction guides.
(Though using
\lstinline
|initializer
_
list| already allows errors.)
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
A real example
}
\begin{lstlisting}
typename<int dim, typename K>
class CNoOffset;
typename<int dim, typename K>
class COffset;
template<int dim,
typename C=CNoOffset<dim, double> >
class Grid
{
using K = typename C::...;
YaspGrid(Vec<K, dim> ur,
std::array<int, size
_
t
{
dim
}
> n);
YaspGrid(Vec<K, dim> ll, Vec<K, dim> ur,
std::array<int, size
_
t
{
dim
}
> n);
}
;
\end{lstlisting}
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
A real example II
}
Assume there was no default for
\lstinline
|C| and define
\begin{lstlisting}
template<int dim, typename K>
Grid(Vec<K, dim>, std::array<int, size
_
t
{
dim
}
>)
-> Grid< dim, CNoOffset<dim, K> >;
template<int dim, typename K>
Grid(Vec<K, dim>, Vec<K, dim>,
std::array<int, size
_
t
{
dim
}
>)
-> Grid< dim, COffset<dim, K> >;
\end{lstlisting}
\pause
then
\begin{lstlisting}
Vector<float, 2> ll =
{
1., 1.
}
, ur =
{
2., 2.
}
;
std::array n =
{
10, 10
}
;
auto g1 = Grid(ur, n);
auto g2 = Grid(ll, ur, n);
\end{lstlisting}
work as they should.
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
A real example IV
}
With default for
\lstinline
|C| however:
\begin{lstlisting}
auto g1 = Grid(ur, n);
\end{lstlisting}
will use
\lstinline
|CNoOffset<2, double>| (not
\lstinline
|float|).
\begin{lstlisting}
auto g2 = Grid(ll, ur, n);
\end{lstlisting}
will also use
\lstinline
|CNoOffset<2, double>|
instead of
\lstinline
|COffset<2, float>|.
\pause
Why? They use the automatic deduction guides with the default value for
\lstinline
|C|.
Workaround:
\lstinline
|enable
_
if| to enable constructors only for the right
\lstinline
|C|:
\begin{lstlisting}
template<
typename D,
typename=enable
_
if
_
t<is
_
same
_
v<D,CNoOffset<...>>>
Grid(Vec<K, dim>, std::array<int, size
_
t
{
dim
}
>);
\end{lstlisting}
or remove the default.
\end{frame}
\begin{frame}
[fragile]
\frametitle
{
A real example V
}
\begin{lstlisting}
FieldVector<float, 2> ll
{
1.f, 1.f
}
, ur
{
2.f, 2.f
}
;
std::array n
{
10, 10
}
;
YaspGrid grid
{
ur, n
}
;
YaspGrid<2, EquidistantCoordinates<float, 2>>
grid
{
ur, n
}
;
YaspGrid grid
{
ll, ur, n
}
;
YaspGrid<2, EquidistantOffsetCoordinates<float, 2>>
grid
{
ll, ur, n
}
;
\end{lstlisting}
\end{frame}
\begin{frame}
Supported in GCC-7 or later, however more complicated examples
result in internal compiler errors. GCC-8 a bit better.
\end{frame}
\end{document}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment