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

Post on 25-Oct-2021

3 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

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)

• 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

• 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

• 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

• 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

• 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

• 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

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

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

• 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

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

• 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

• 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

• 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

• 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

• 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

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

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

• 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>;

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

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?

• 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

top related