template<typename... Args>
struct types {};
namespace detail {
template<typename... RArgs>
types<RArgs...> reverse_types( types<RArgs...>, types<> ) {
return types<RArgs...>();
}
template<typename Next, typename... Args, typename... RArgs>
auto reverse_types(types<RArgs...>, types<Next, Args...>) -> decltype(reverse_types(types<Next, RArgs...>(), types<Args...>())) {
return reverse_types(types<RArgs..., Next>(), types<Args...>());
}
} // detail
template<typename... Args>
auto reverse_types() -> decltype(detail::reverse_types(types<>(), types<Args...>())) {
return detail::reverse_types(types<>(), types<Args...>());
}
int main() {
struct {} _ = reverse_types<char>();
struct {} __ = reverse_types<char, int>();
return 0;
}
dGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4Kc3RydWN0IHR5cGVzIHt9OwoKbmFtZXNwYWNlIGRldGFpbCB7CnRlbXBsYXRlPHR5cGVuYW1lLi4uIFJBcmdzPgp0eXBlczxSQXJncy4uLj4gcmV2ZXJzZV90eXBlcyggdHlwZXM8UkFyZ3MuLi4+LCB0eXBlczw+ICkgewoJcmV0dXJuIHR5cGVzPFJBcmdzLi4uPigpOwp9CnRlbXBsYXRlPHR5cGVuYW1lIE5leHQsIHR5cGVuYW1lLi4uIEFyZ3MsIHR5cGVuYW1lLi4uIFJBcmdzPgphdXRvIHJldmVyc2VfdHlwZXModHlwZXM8UkFyZ3MuLi4+LCB0eXBlczxOZXh0LCBBcmdzLi4uPikgLT4gZGVjbHR5cGUocmV2ZXJzZV90eXBlcyh0eXBlczxOZXh0LCBSQXJncy4uLj4oKSwgdHlwZXM8QXJncy4uLj4oKSkpIHsKCXJldHVybiByZXZlcnNlX3R5cGVzKHR5cGVzPFJBcmdzLi4uLCBOZXh0PigpLCB0eXBlczxBcmdzLi4uPigpKTsKfQp9IC8vIGRldGFpbAoKdGVtcGxhdGU8dHlwZW5hbWUuLi4gQXJncz4KYXV0byByZXZlcnNlX3R5cGVzKCkgLT4gZGVjbHR5cGUoZGV0YWlsOjpyZXZlcnNlX3R5cGVzKHR5cGVzPD4oKSwgdHlwZXM8QXJncy4uLj4oKSkpIHsKCXJldHVybiBkZXRhaWw6OnJldmVyc2VfdHlwZXModHlwZXM8PigpLCB0eXBlczxBcmdzLi4uPigpKTsKfQoKaW50IG1haW4oKSB7CgkKCXN0cnVjdCB7fSBfID0gcmV2ZXJzZV90eXBlczxjaGFyPigpOwoJc3RydWN0IHt9IF9fID0gcmV2ZXJzZV90eXBlczxjaGFyLCBpbnQ+KCk7CgkKCXJldHVybiAwOwp9
prog.cpp: In function ‘int main()’:
prog.cpp:22:36: error: conversion from ‘types<char>’ to non-scalar type ‘main()::<anonymous struct>’ requested
struct {} _ = reverse_types<char>();
^
prog.cpp:23:42: error: no matching function for call to ‘reverse_types()’
struct {} __ = reverse_types<char, int>();
^
prog.cpp:23:42: note: candidate is:
prog.cpp:16:6: note: template<class ... Args> decltype (detail::reverse_types(types<>(), types<RArgs ...>())) reverse_types()
auto reverse_types() -> decltype(detail::reverse_types(types<>(), types<Args...>())) {
^
prog.cpp:16:6: note: template argument deduction/substitution failed:
prog.cpp: In substitution of ‘template<class ... Args> decltype (detail::reverse_types(types<>(), types<RArgs ...>())) reverse_types() [with Args = {char, int}]’:
prog.cpp:23:42: required from here
prog.cpp:16:83: error: no matching function for call to ‘reverse_types(types<>, types<char, int>)’
auto reverse_types() -> decltype(detail::reverse_types(types<>(), types<Args...>())) {
^
prog.cpp:16:83: note: candidates are:
prog.cpp:6:17: note: template<class ... RArgs> types<RArgs ...> detail::reverse_types(types<RArgs ...>, types<>)
types<RArgs...> reverse_types( types<RArgs...>, types<> ) {
^
prog.cpp:6:17: note: template argument deduction/substitution failed:
prog.cpp:16:83: note: cannot convert ‘types<char, int>()’ (type ‘types<char, int>’) to type ‘types<>’
auto reverse_types() -> decltype(detail::reverse_types(types<>(), types<Args...>())) {
^
prog.cpp:10:6: note: template<class Next, class ... Args, class ... RArgs> decltype (detail::reverse_types(types<Next, RArgs ...>(), types<Args ...>())) detail::reverse_types(types<RArgs ...>, types<Next, Args ...>)
auto reverse_types(types<RArgs...>, types<Next, Args...>) -> decltype(reverse_types(types<Next, RArgs...>(), types<Args...>())) {
^
prog.cpp:10:6: note: template argument deduction/substitution failed:
prog.cpp: In substitution of ‘template<class Next, class ... Args, class ... RArgs> decltype (detail::reverse_types(types<Next, RArgs ...>(), types<Args ...>())) detail::reverse_types(types<RArgs ...>, types<Next, Args ...>) [with Next = char; Args = {int}; RArgs = {}]’:
prog.cpp:16:83: required by substitution of ‘template<class ... Args> decltype (detail::reverse_types(types<>(), types<RArgs ...>())) reverse_types() [with Args = {char, int}]’
prog.cpp:23:42: required from here
prog.cpp:10:126: error: no matching function for call to ‘reverse_types(types<char>, types<int>)’
auto reverse_types(types<RArgs...>, types<Next, Args...>) -> decltype(reverse_types(types<Next, RArgs...>(), types<Args...>())) {
^
prog.cpp:10:126: note: candidates are:
prog.cpp:6:17: note: template<class ... RArgs> types<RArgs ...> detail::reverse_types(types<RArgs ...>, types<>)
types<RArgs...> reverse_types( types<RArgs...>, types<> ) {
^
prog.cpp:6:17: note: template argument deduction/substitution failed:
prog.cpp:10:126: note: cannot convert ‘types<int>()’ (type ‘types<int>’) to type ‘types<>’
auto reverse_types(types<RArgs...>, types<Next, Args...>) -> decltype(reverse_types(types<Next, RArgs...>(), types<Args...>())) {
^
prog.cpp:16:6: note: template<class ... Args> decltype (detail::reverse_types(types<>(), types<RArgs ...>())) reverse_types()
auto reverse_types() -> decltype(detail::reverse_types(types<>(), types<Args...>())) {
^
prog.cpp:16:6: note: template argument deduction/substitution failed:
prog.cpp:10:126: note: candidate expects 0 arguments, 2 provided
auto reverse_types(types<RArgs...>, types<Next, Args...>) -> decltype(reverse_types(types<Next, RArgs...>(), types<Args...>())) {
^
prog.cpp:23:12: warning: unused variable ‘__’ [-Wunused-variable]
struct {} __ = reverse_types<char, int>();
^