https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97852
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> --- I don't think this is valid, t cannot show up in a constexpr. ICC rejects this with a decent error message too: <source>(3): error: a parameter is not allowed And if we use foo MSVC rejects it: <source>(7): error C2672: 'foo': no matching overloaded function found <source>(7): error C2770: invalid explicit template argument(s) for 'S<int,t,N...> foo(T)' <source>(3): note: see declaration of 'foo' That is: template <typename T, T...> struct S {}; template <typename T, long... N> auto foo(T t) -> S<decltype(0), (t, N)...>; auto g(void) { return foo<int, 1>(100); } Note I don't think the original is valid either. Take this C++17 code: template <typename T, T...> struct S {}; constexpr int f(int, long) { return 0;} template <typename T, long... N> constexpr auto foo(int t) { S<decltype(0), f(t, N)...> t1; return t1; } auto g(void) { return foo<int, 1>(100); } ---- CUT ---- All compilers reject this above code as invalid. GCC with: <source>: In instantiation of 'constexpr auto foo(int) [with T = int; long int ...N = {1}]': <source>:13:23: required from here <source>:7:32: error: 't' is not a constant expression 7 | S<decltype(0), f(t, N)...> t1; | ^~ <source>:7:21: note: in template argument for type 'int' 7 | S<decltype(0), f(t, N)...> t1; | ~^~~~~~ <source>:7:32: error: 't' is not a constant expression 7 | S<decltype(0), f(t, N)...> t1; | ^~ <source>:7:21: note: in template argument for type 'int' 7 | S<decltype(0), f(t, N)...> t1; | ~^~~~~~ Clang with <source>:7:20: error: non-type template argument is not a constant expression S<decltype(0), f(t, N)...> t1; ^~~~~~~ <source>:13:12: note: in instantiation of function template specialization 'foo<int, 1L>' requested here return foo<int, 1>(100); ^ <source>:7:22: note: function parameter 't' with unknown value cannot be used in a constant expression S<decltype(0), f(t, N)...> t1; ^ <source>:5:57: note: declared here template <typename T, long... N> constexpr auto foo(int t) ^ this is similar to workaround 2 but with an instantiation to show that workaround 2 does not work really.