Zalety auto w parametrach szablonu w C++17

Jakie są zalety auto w parametrach szablonu, które (ewentualnie) zostaną wprowadzone w C++17?

Czy jest to tylko naturalne rozszerzenie auto Kiedy chcę utworzyć instancję kodu szablonu?

auto v1 = constant<5>;      // v1 == 5, decltype(v1) is int
auto v2 = constant<true>;   // v2 == true, decltype(v2) is bool
auto v3 = constant<'a'>;    // v3 == 'a', decltype(v3) is char

Co jeszcze zyskuję dzięki tej funkcji językowej?

Author: Damian, 2016-06-25

4 answers

Funkcja template <auto> ( P0127R1 ) została przyjęta do C++ na spotkaniu ISO C++ 2016 w Oulu w Finlandii.

Słowo kluczowe auto w parametrze szablonu może być użyte do wskazania parametru innego niż typ, którego typ jest wydedukowany w punkcie tworzenia instancji. To pomaga myśleć o tym jako o wygodniejszym sposobie pisania:

template <typename Type, Type value>

Na przykład,

template <typename Type, Type value> constexpr Type constant = value;
constexpr auto const IntConstant42 = constant<int, 42>;

Można teraz zapisać jako

template <auto value> constexpr auto constant = value;
constexpr auto const IntConstant42 = constant<42>;

Gdzie nie musisz już wyraźnie określać typu. P0127R1 zawiera również kilka prostych, ale dobrych przykładów, gdzie użycie template <auto> z zmiennymi parametrami szablonu jest bardzo przydatne, na przykład dla implementacji wartości stałych list w czasie kompilacji:

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 13u>;

template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {};
using MyList2 = HomogenousValueList<1, 2, 3>;

W pre-c++1z, natomiast {[9] } można po prostu zapisać jako

template <typename T, T ... vs> struct Cxx14HomogenousValueList {};
using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>;

Zapis odpowiednika HeterogenousValueList nie byłby możliwy bez zawijania wartości w innych szablonach, na przykład:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {};
using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,
                                           constant<char, 'X'> >;
 73
Author: mceo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-11 22:09:09

W rzeczywistości przypadek rzeczywistych wartości w odpowiedzi mceo (oryginalnej) nie jest wyraźnie ujęty jako parametr szablonu innego niż typ.

template <auto ... vs> struct HeterogenousValueList {};
using MyList1 = HeterogenousValueList<42, 'X', 1.3f>;

Patrz przykład podany we wspomnianej propozycji: Zmienić §14.3.2 pkt 2:

template<auto n> struct B { /* ... */ };
B<5> b1;   // OK: template parameter type is int
B<'a'> b2; // OK: template parameter type is char
B<2.5> b3; // error: template parameter type cannot be double
Kilka dni temu natknąłem się na to samo nieporozumienie.
 13
Author: m-j-w,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-16 22:33:18

Oto kolejny przykład (pierwotnie przedstawiony przez @ Rakete1111 jako odpowiedź na szablon parametr szablonu nieznanego typu):

Wydobywanie wartości rozmiaru bez znajomości jego typu:

template<std::size_t SIZE>
class Foo {};

template <template<auto> class T, auto K>
auto extractSize(const T<K>&) {
    return K;
}

int main() {
    Foo<6> f1;
    Foo<13> f2;
    std::cout << extractSize(f1) << std::endl;
    std::cout << extractSize(f2) << std::endl;
}
 6
Author: Amir Kirsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-04 14:24:48

C++2010]}

... ale nie: - (

Koncepcje Specyfikacja techniczna dopuszczała parametr funkcji z auto szablonowym argumentem zastępczym, np.:

void printPair(const std::pair<auto, auto>& p) {
    std::cout << p.first << ", " << p.second << std::endl;
}

Ale został usunięty później w specyfikacji C++20.

To jest schludne użycie... mam nadzieję, że znowu wejdzie w C++23!

Zobacz: 'auto' jako element zastępczy argumentu szablonu dla parametru funkcji

 1
Author: Amir Kirsh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-02 01:15:25