Viewing file: variadic-alias2.C (2.79 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// PR c++/91966 // { dg-do compile { target c++11 } }
// Reduced to this include-free example. Further reduction is hard: Either // the bug(?) disappears, or the program becomes meaningless.
template<class...> struct list {};
struct nil;
////////////////////////////////////////////////////////////////////////////////
template<int n> struct number { constexpr /*implicit*/ operator int() const { return n; } using type = number<n>; };
using false_ = number<0>; using true_ = number<1>;
static_assert(!false_{}, ""); static_assert(true_{}, "");
template<int... ns> using numbers = list<number<ns>...>;
////////////////////////////////////////////////////////////////////////////////
template<class lhs, class rhs> struct less_impl;
template<int lhs, int rhs> struct less_impl<number<lhs>, number<rhs>> : number<(lhs < rhs)> {};
template<class lhs, class rhs> using less = typename less_impl<lhs, rhs>::type;
////////////////////////////////////////////////////////////////////////////////
template<class v0, class... vs> struct sum_impl { static_assert(sizeof...(vs) == 0, "see specialization"); using type = v0; };
template<int v0, int v1, class... vs> struct sum_impl<number<v0>, number<v1>, vs...> : sum_impl<number<v0 + v1>, vs...> {};
template<class... nums> using sum = typename sum_impl<nums...>::type;
////////////////////////////////////////////////////////////////////////////////
template<class num> struct conditional_impl { static_assert(num{}, "see specialization");
template<class T, class F> using type = T; };
template<> struct conditional_impl<false_> { template<class T, class F> using type = F; };
template<class num, class T, class F> using conditional = typename conditional_impl<num>::template type<T, F>;
////////////////////////////////////////////////////////////////////////////////
template<class seq> struct min_filter_impl;
template<class... nums> struct min_filter_impl<list<nums...>> { template<class num> using count_better_mins = sum<less<nums, num>...>;
using type = list<conditional<count_better_mins<nums>, nil, nums>...>;
//using debug = list<conditional<count_better_mins<nums>, nil, void>...>;
// error: expansion pattern 'conditional<typename sum_impl<less<nums, nums>...>::type, nil, void>' contains no parameter packs
};
template<class seq> using min_filter = typename min_filter_impl<seq>::type;
////////////////////////////////////////////////////////////////////////////////
void test_min_filter() { using computed = min_filter<numbers<2, 7, 2>>; using expected = list<number<2>, nil, number<2>>; (void)(computed{} = expected{});// compiles for identical types
// error: no match for 'operator=' (operand types are 'computed' {aka 'list<number<2>, number<7>, number<2> >'} and 'expected' {aka 'list<number<2>, nil, number<2> >'})
}
int main() {}
|