https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67878
Bug ID: 67878 Summary: [concepts] when processing a valid concept check, gcc errors trying to expand variadic in unrelated code Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ryan.burn at gmail dot com Target Milestone: --- The below code should be valid, but gcc gives the following error, which references a completely unrelated concept: t2.cpp:42:53: error: expansion pattern ‘indexes#0’ contains no argument packs requires cpt_Scalar<uncvref_t<decltype(evaluator(indexes...))>>(); ^ t2.cpp: In function ‘int main()’: t2.cpp:89:42: error: cannot call function ‘auto make_indexed_evaluator(const Evaluator&) [with long unsigned int K = 2ul; Evaluator = main()::<lambda(index_t, index_t, index_t, index_t)>]’ auto f1_ = make_indexed_evaluator<2>(f1); ^ t2.cpp:81:6: note: constraints not satisfied auto make_indexed_evaluator(const Evaluator& evaluator) { ^ t2.cpp:81:6: note: concept ‘cpt_IndexedEvaluatable<main()::<lambda(index_t, index_t, index_t, index_t)>, 2ul>()’ was not satisfied ////////////////////////////////////////////////////////////////////////////////// #include <type_traits> #include <utility> using index_t = long; //------------------------------------------------------------------------------ // repeat_type_c //------------------------------------------------------------------------------ namespace DETAIL_NS { template <unsigned long long, class T> struct repeat_type_c_impl { using type = T; }; } template <unsigned long long A, class T> using repeat_type_c = typename DETAIL_NS::repeat_type_c_impl<A, T>::type; //------------------------------------------------------------------------------ // uncvref_t //------------------------------------------------------------------------------ template <class T> using uncvref_t = typename std::remove_cv<typename std::remove_reference<T>::type>::type; //------------------------------------------------------------------------------ // cpt_Scalar //------------------------------------------------------------------------------ template <class X> concept bool cpt_Scalar() { return std::is_floating_point<X>::value; } //------------------------------------------------------------------------------ // cpt_KEvaluator //------------------------------------------------------------------------------ namespace DETAIL_NS { template <class, class> constexpr bool k_evaluator_impl = false; // clang-format off template <std::size_t... Indexes, class Evaluator> requires requires(const Evaluator& evaluator, repeat_type_c<Indexes, index_t>... indexes) { requires cpt_Scalar<uncvref_t<decltype(evaluator(indexes...))>>(); &Evaluator::operator(); } constexpr bool k_evaluator_impl<std::index_sequence<Indexes...>, Evaluator> = true; // clang-format on } template <class X, std::size_t K> concept bool cpt_KEvaluator() { return DETAIL_NS::k_evaluator_impl<std::make_index_sequence<2 * K>, X>; } //------------------------------------------------------------------------------ // cpt_IndexedEvaluatable //------------------------------------------------------------------------------ namespace DETAIL_NS { template <class, class> constexpr bool indexed_evaluatable_impl = false; // clang-format off template <std::size_t... Indexes, class Evaluator> requires requires(const Evaluator& evaluator, repeat_type_c<Indexes, index_t>... indexes) { requires cpt_Scalar<uncvref_t<decltype(evaluator(indexes...))>>(); } constexpr bool indexed_evaluatable_impl< std::index_sequence<Indexes...>, Evaluator> = true; // clang-format on } template <class Evaluator, std::size_t K> concept bool cpt_IndexedEvaluatable() { return DETAIL_NS::indexed_evaluatable_impl<std::make_index_sequence<2 * K>, Evaluator>; } //------------------------------------------------------------------------------ // make_indexed_evaluator //------------------------------------------------------------------------------ template <std::size_t K, cpt_IndexedEvaluatable<K> Evaluator> auto make_indexed_evaluator(const Evaluator& evaluator) { return true; } int main() { auto f1 = [](index_t i, index_t m, index_t j, index_t n) { return 2.0; }; auto f1_ = make_indexed_evaluator<2>(f1); return 0; } //////////////////////////////////////////////////////////////////////////////////