Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are checked guard parameter packs cause of ill-formed programs?

More than once (even on SO) I've seen code like this:

template<typename U, typename... G, typename T = Traits<U>>
struct {
    static_assert(sizeof...(G) == 0, "!");
    // ...
};

Or this:

template<typename T, typename... G, typename = std::enable_if_t<condition<T>>
void func(T &&t) {
    static_assert(sizeof...(G) == 0, "!");
    // ....
}

The intent was to avoid users break the rule of the game by doing something like this:

template<typename T, typename = std::enable_if_t<std::is_same<T, int>>
void func(T &&t) {
    // ....
}

// ...

func<int&, void>(my_int);

With the guard parameter pack, the defaulted value cannot be overridden.
On the other side, the check on the size avoids pollution of the specializations with useless parameters.

Anyway, because of [temp.res/8], we have that:

The program is ill-formed, no diagnostic required, if:
[...]
- every valid specialization of a variadic template requires an empty template parameter pack, or
[...]

Therefore, are the programs that contain the above mentioned snippets ill-formed or not?

like image 608
skypjack Avatar asked Oct 16 '16 22:10

skypjack


1 Answers

The "trick" results in an ill formed program, no diagnostic required.

The standard states it clearly in the section you quoted.

like image 155
Yakk - Adam Nevraumont Avatar answered Nov 05 '22 11:11

Yakk - Adam Nevraumont