templates with strings and auto in c++17 - tum

23
Technical University of Munich Faculty of Informatics Chair for Computer Aided Medical Procedures Tobias Jülg Garching, 05. June 2018 Templates with Strings and auto in C++17

Upload: others

Post on 25-Oct-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Templates with Strings and auto in C++17 - TUM

Technical University of Munich

Faculty of Informatics

Chair for Computer Aided Medical Procedures

Tobias Jülg

Garching, 05. June 2018

Templates with Strings and auto in C++17

Page 2: Templates with Strings and auto in C++17 - TUM

Trend:

Shifting calculations towards compile time

• Limited execution time

• constexpr simplified metaprogramming a lot → interesting use cases

• E. g. regex libraries that analyse strings at compile time

→Simplifying syntax for strings and pushing modern concepts like auto to template development

2Tobias Jülg (TUM)

Page 3: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using auto

▪ Applications

• References

• Exercises

3Tobias Jülg (TUM)

Agenda

Page 4: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using auto

▪ Applications

• References

• Exercises

4Tobias Jülg (TUM)

Agenda

Page 5: Templates with Strings and auto in C++17 - TUM

• Type Templates

→ Compiler generates code with the replaced types

template <typename T> // T as typevariable

void Print(T p) {

std::cout << p << std::endl;

}

Print(0.5f); // T is deduced to float

• Non-Type Templates

→ Compiler generates code with the replaced values instead of types

→ Example: std::array

template<typename T, std::size_t N>

class Array {

T m_Array[N];

};

Array<int, 10> a;

5Tobias Jülg (TUM)

Short Reminder of Templates

Page 6: Templates with Strings and auto in C++17 - TUM

• Values must be constant expressions

• Allowed types:

− const integral values, also enums

− pointers to objects/functions/members

− lvalue references to objects, functions or std::nullptr_t

• Implicit value deduction:

template<std::size_t N>

std::size_t GetSize(const int(&arr)[N]) {

return N;

}

int arr[10];

std::size_t n = GetSize(arr); //n will be 10

6Tobias Jülg (TUM)

Non-Type Templates

→ Advantages compared to passing• Values are known at compile time

• Compile time analysis, faster

Page 7: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using auto

▪ Applications

• References

• Exercises

7Tobias Jülg (TUM)

Agenda

Page 8: Templates with Strings and auto in C++17 - TUM

• Properties of Variables

− Linkage: internal, external or non at all

− Scope: global or local scope (heap or stack)

− Duration: static or temporary duration

• When using strings as arguments− Linkage is always required

− You can’t pass string literals directly, instead const char*

− Rules for relaxed over time

• Situation before C++17− C++98 pointer parameters work only with external linkage

− C++11 internal linkage possible but only global scope

8Tobias Jülg (TUM)

Strings as Non-Type Template Parameters

Page 9: Templates with Strings and auto in C++17 - TUM

In C++17

→Using pointers, defined in the current scope possible when declared static

→Still two lines of code but doesn’t pollute the global namespace

→Easier to use C-Strings

→Upcoming use cases: Compile-time JSON and regular expression parsing

template<const char *str>

class regex_parser { };

extern const char hello[] = "[a-zA-Z]*"; //external linkage

const char hello11[] = "C++11 [a-zA-Z]*"; //internal linkage

void foo() {

regex_parser<hello> msg; //okay for all C++ versions

regex_parser<hello11> msg11; //okay since C++11

static const char hello17[] = "C++17 [a-zA-Z]*"; //static declaration

regex_parser<hello17> msg17; //okay since C++17

}

9Tobias Jülg (TUM)

Strings as Non-Type Template Parameters

Page 10: Templates with Strings and auto in C++17 - TUM

Before C++17

• You could pass a normal pointer to a

class template

• Compile-time functions returning the

address weren’t possible

• Except functions returning a nullptr

• Implementation only to evaluate the

return type

→ In C++17 by allowing static pointers this

inconsistency was fixed

10Tobias Jülg (TUM)

Pointers returned by Functions

template<int *p> struct A {};int n;A<&n> a; // OK

constexpr int *q() { return nullptr; }A<q()> c; // OK before C++17 because it

// returns a nullptr

constexpr int *p() { return &n; }A<p()> b; // error before C++17, now OK

Page 11: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using auto

▪ Applications

• References

• Exercises

11Tobias Jülg (TUM)

Agenda

Page 12: Templates with Strings and auto in C++17 - TUM

Before C++17, when you didn't want to write a explicit type for a non-type template

// I don't want to be specified on int here

template<int N> struct S { };

the following workaround was possible. Be x of any type:

template <typename T, T N> struct S { }; // definition

template<typename T> void foo(T x) {

S<decltype(x), x> s; // instantiation, x is of any type

}

• Type of x isn’t needed but has to be passed

→ redundancy

• Can get more complicated when passing function without fixed type

→ variadic functions

12Tobias Jülg (TUM)

Placeholder Types as Template Parameters

Page 13: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using of auto

▪ Applications

• References

• Exercises

13Tobias Jülg (TUM)

Agenda

Page 14: Templates with Strings and auto in C++17 - TUM

• Like you use it in lambdas you can also use it with templates now

• In C++ 17 the auto keyword was introduced for non-typed templates

• → known as template <auto>

• → You don’t have to mind the types and let the compiler deduce it

• → Extremely useful for passing a function pointer with non-fixed types

Way to do the previous example in C++17:

template<auto N> struct S { };

S<42> s1; // OK type N is int

S<'a'> s2; // OK type N is char

S<2.5> s3; // Error

→ Can only deduce allowed types for templates

14Tobias Jülg (TUM)

Using auto as Template Parameter

Page 15: Templates with Strings and auto in C++17 - TUM

• You can also qualify auto like you do when using it with normal variables, for example to

require a pointer:

template<const auto* p>struct S { };

• Partial specialization

template<int M, int E> struct S { /*do some recursion*/ };

template<int M> struct S<M, 0> {

// end recursion when E is 0 --> different implementation

};

→ Also works for the auto types, for example for int

template<auto N> struct S { };

template<int N> struct S<N> {

// specialized implementation when N is of type int

};

15Tobias Jülg (TUM)

Further features

Page 16: Templates with Strings and auto in C++17 - TUM

• Even class template argument deduction is supported

template<typename T, auto N> struct A {

A(const std::array<T, N>&) { }

};

std::array<double, 10> sa1;

A a1{sa1}; // OK

→ Compiler deduces the types T being double and N being std::size_t without specifying it

16Tobias Jülg (TUM)

Further features

Page 17: Templates with Strings and auto in C++17 - TUM

• Motivation

• Short Reminder of Templates

• New C++17 features

− Strings as non-type Template Parameters

− Placeholder Types as Template Parameters

▪ Using of auto

▪ Applications

• References

• Exercises

17Tobias Jülg (TUM)

Agenda

Page 18: Templates with Strings and auto in C++17 - TUM

auto allows to pass both a character or a c-string as template parameter

→ create a print function that accepts any number of parameters and make the separator

type independent:

template<auto Sep = ' ', typename First, typename... Args>

void print(const First& first, const Args&... args) {

std::cout << first;

auto outWithSpace = [](const auto& arg) {

std::cout << Sep << arg;

};

(..., outWithSpace(args));

std::cout << '\n’;

}

18Tobias Jülg (TUM)

Application: Parameterizing Templates

Page 19: Templates with Strings and auto in C++17 - TUM

auto allows to pass both a character or a c-string as template parameter

→ create a print function that accepts any number of parameters and make the separator

type independent:template<auto Sep = ' ', typename First, typename... Args>

void print(const First& first, const Args&... args) {

std::cout << first;

auto outWithSpace = [](const auto& arg) {

std::cout << Sep << arg;

};

(..., outWithSpace(args));

std::cout << '\n’;

}

Pass the default Argument for the first template:std::string s{ "world" };

print(7.5, "hello", s); // prints: 7.5 hello world

Pass a string literal as separator:static const char sep[] = ", ";

print<sep>(7.5, "hello", s); // prints: 7.5, hello, world

19Tobias Jülg (TUM)

Application: Parameterizing Templates

→ Basically any type that can

be used as template

parameter

→ Runtime improvement for

logger functions

Page 20: Templates with Strings and auto in C++17 - TUM

• Metaprogramming constants also needed to pass the type

• auto improves the instantiation process of these constants:

→ Like auto with normal variables you don’t need to pass the type

20Tobias Jülg (TUM)

Application: Defining Metaprogramming Constants

template<auto v>struct constant{

static constexpr auto value = v;};using i = constant<42>;

template<typename T, T v>struct constant{

static constexpr T value = v;};using i = constant<int, 42>;

Page 21: Templates with Strings and auto in C++17 - TUM

And when using a sequence with variadic template syntax instead of

template<typename T, T... Elements>

struct sequence {};

using indexes = sequence<int, 0, 3, 4>;

There are new possibilities to parameterize a list of constant template arguments:

• At least one argument and all having the same type:

template<auto V1, decltype(V1)... VS> struct HomoValueSequence {};

• Even compile-time objects representing a heterogeneous list of values like a tuple:

template<auto... VS> struct HeteroValueSequence {};

using tuple = HeteroValueSequence<0, 'h', true>;

21Tobias Jülg (TUM)

Application: Defining Metaprogramming Constants

Page 22: Templates with Strings and auto in C++17 - TUM

template<typename T, T... Elements> class Foo0 {};

template<auto... VS> class Foo1 { };

template<auto V1, decltype(V1)... VS> class Foo2 { };

Foo0<1, 'a', true> vals1;

Foo0<int, 1, 2, 3> vals2;

Foo0<> vals3;

Foo1<1, 2, 3> vals4;

Foo1<1, 'a', true> vals5;

Foo1<> vals6;

Foo2<> vals7;

Foo2<1, 'a', true> vals8;

Foo2<1, 2, 3> vals9;

22Tobias Jülg (TUM)

Which lines won’t compile?

Page 23: Templates with Strings and auto in C++17 - TUM

• Nicolai Josuttis, C++17 - The Complete Guide, ch. 12, 13, leanpub, 02.2017

• Louis Dionne, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0424r2.pdf,

visited May 2018

• Louis Dionne, https://ldionne.com/2015/11/29/efficient-parameter-pack-indexing/ visited

May 2018

• Richard Smith, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4268.html

visited May 2018

• James Touton, http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0127r1.html

visited May 2018

23Tobias Jülg (TUM)

References