Skip to content

Template improvements

Compile-time if feature

struct Coord
{
    double x;
    double y;
};

// tuple like access to coords via get<1>(), get<2>()
template<std::size_t> auto get(const Coord&);
template<std::size_t N> auto get(const Coord& c)
{
    static_assert(N > 0);
    static_assert(N < 3);
    if constexpr (N == 1)
    {
        return c.x;
    }
    else
    {
        return c.y;
    }
}

Instead of writing multiple specific template functions you can write a single function which internally checks the alternatives with compile-time if.

Class template argument deduction (CTAD)

With C++ 17 template types can be deduced from the used arguments:

std::mutex m;
std::lock_guard lock(m); // => lock_guard automatically uses type std::mutex
  • deduction prefers interpretation as initializing a copy if possible
  • deduction of reference types does not use “decay”, i.e. param “Hi” (raw array) keep its type const char[3]
  • deduction of value types supports “decay”, i.e. param “Hi” is deduced to const char *
  • deduction guides for a template constructor can change this behaviour:
    template<typename T1, typename T2> SomeTemplClass(T1,T2) -> SomeTemplClass<T1, T2>;
    => constructor param type may be of reference type or not
template<typename T>
struct S
{
    T val;
};

// non template deduction guide
S(const char*) -> S<std::string>;

S myString("Hi"); // uses type S<std::string>

Conditionally explicit constructor

You can allow implicit conversions only for specific types by defining key word “explicit” only in dependence of the used type:

#include <type_traits>
struct MyClass
{
    // Generic constructor
    template <typename T>
    explicit(!std::is_same<T, bool>::value) MyClass(T t){..}
};

// Usage: only for bool values direct assignment is possible:
MyClass c1 = true;
MyClass c2 = 45; // ERROR
MyClass c3{45}; ok

Non-type template parameters

With C++20 the following non-types are allowed:

  • integers and enums
  • std::nullptr_t
  • pointers or references to objects/functions/class attributes
  • floating point values
  • string literals
  • literal types (classes with constexpr constructor and public structural data and public base classes)