samedi 30 septembre 2017

template, well formedness and zero pack length rule

From the accepted answer of a previous question I've discovered a rule I didn't know about templates and well formedness

The program is ill-formed, no diagnostic required, if:

  • [...]
  • every valid specialization of a variadic template requires an empty template parameter pack, or
  • [...]

According this rule (if I understand correctly), the following template function is ill-formed

template <typename ... Ts>
int foo (std::tuple<Ts...> const &)
 { return std::get<sizeof...(Ts)>(std::tuple<int>{42}); }

because the only valid specialization require and empty Ts... parameter pack.

But (maybe because I don't know English very well) I'm not sure to understand this rule in case of a template with two ore more parameter packs.

I mean... the following foo() function

#include <tuple>
#include <iostream>

template <typename ... Ts, typename ... Us>
int foo (std::tuple<Ts...> const &, std::tuple<Us...> const &)
 { return std::get<sizeof...(Ts)+sizeof...(Us)-1U>(std::tuple<int>{42}); }

int main ()
 {
   auto t0 = std::tuple<>{};
   auto t1 = std::tuple<int>{0};

   //std::cout << foo(t0, t0) << std::endl; // compilation error
   std::cout << foo(t0, t1) << std::endl;   // print 42
   std::cout << foo(t1, t0) << std::endl;   // print 42
   //std::cout << foo(t1, t1) << std::endl; // compilation error
 }

is well-formed or ill-formed?

Because a valid specialization of it require that Ts... or Us... is empty (and that the other parameter pack is exactly of size 1).

The rule should be interpreted in the sense that a programm is ill-formed if there is an empty parameter pack that must be ever empty (so my example should be well formed because both parameter packs can be not empty) or in the sense that is ill-formed if in every specialization there is at least an empty parameter pack, not necessarily the same in every specialization (so my example should be ill-formed) ?

Aucun commentaire:

Enregistrer un commentaire