562 lines · cpp
1// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -fblocks -fms-extensions -fsyntax-only -verify=expected,cxx11 %s2// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++23 -fblocks -fms-extensions -fsyntax-only -verify=expected %s3 4template<typename T, typename U> struct pair;5template<typename ...> struct tuple;6 7// A parameter pack whose name appears within the pattern of a pack8// expansion is expanded by that pack expansion. An appearance of the9// name of a parameter pack is only expanded by the innermost10// enclosing pack expansion. The pattern of a pack expansion shall11// name one or more parameter packs that are not expanded by a nested12// pack expansion.13template<typename... Types>14struct Expansion {15 typedef pair<Types..., int> expand_with_pacs; // okay16 typedef pair<Types, int...> expand_no_packs; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}17 typedef pair<pair<Types..., int>..., int> expand_with_expanded_nested; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}18};19 20// All of the parameter packs expanded by a pack expansion shall have21// the same number of arguments specified.22template<typename ...Types>23struct ExpansionLengthMismatch {24 template<typename ...OtherTypes>25 struct Inner {26 typedef tuple<pair<Types, OtherTypes>...> type; // expected-error{{pack expansion contains parameter packs 'Types' and 'OtherTypes' that have different lengths (3 vs. 2)}}27 };28};29 30ExpansionLengthMismatch<int, long>::Inner<unsigned int, unsigned long>::type31 *il_pairs;32tuple<pair<int, unsigned int>, pair<long, unsigned long> >*il_pairs_2 = il_pairs;33 34ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>::type // expected-note{{in instantiation of template class 'ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>' requested here}}35 *il_pairs_bad;36 37 38// An appearance of a name of a parameter pack that is not expanded is39// ill-formed.40 41// Test for unexpanded parameter packs in each of the type nodes.42template<typename T, int N, typename ... Types>43struct TestPPName44 : public Types, public T // expected-error{{base type contains unexpanded parameter pack 'Types'}}45{46 // BuiltinType is uninteresting47 // FIXME: ComplexType is uninteresting?48 // PointerType49 typedef Types *types_pointer; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}50 51 // BlockPointerType52 typedef Types (^block_pointer_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}53 typedef int (^block_pointer_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}54 55 // LValueReferenceType56 typedef Types &lvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}57 58 // RValueReferenceType59 typedef Types &&rvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}60 61 // MemberPointerType62 typedef Types TestPPName::* member_pointer_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}63 typedef int Types::*member_pointer_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}64 65 // ConstantArrayType66 typedef Types constant_array[17]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}67 68 // IncompleteArrayType69 typedef Types incomplete_array[]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}70 71 // VariableArrayType72 void f(int i) { // expected-note {{declared here}}73 Types variable_array[i]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}} \74 expected-warning {{variable length arrays in C++ are a Clang extension}} \75 expected-note {{function parameter 'i' with unknown value cannot be used in a constant expression}}76 }77 78 // DependentSizedArrayType79 typedef Types dependent_sized_array[N]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}80 81 // DependentSizedExtVectorType82 typedef Types dependent_sized_ext_vector __attribute__((ext_vector_type(N))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}83 84 // VectorType is uninteresting85 86 // ExtVectorType87 typedef Types ext_vector __attribute__((ext_vector_type(4))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}88 89 // FunctionProtoType90 typedef Types (function_type_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}91 typedef int (function_type_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}92 93 // FunctionNoProtoType is uninteresting94 // UnresolvedUsingType is uninteresting95 // ParenType is uninteresting96 // TypedefType is uninteresting97 98 // TypeOfExprType99 typedef __typeof__((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}100 101 // TypeOfType102 typedef __typeof__(Types) typeof_type; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}103 104 // DecltypeType105 typedef decltype((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}106 107 // RecordType is uninteresting108 // EnumType is uninteresting109 // ElaboratedType is uninteresting110 111 // TemplateTypeParmType112 typedef Types template_type_parm; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}113 114 // SubstTemplateTypeParmType is uninteresting115 116 // TemplateSpecializationType117 typedef pair<Types, int> template_specialization; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}118 119 // InjectedClassName is uninteresting.120 121 // DependentNameType122 typedef typename Types::type dependent_name; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}123 124 // DependentTemplateSpecializationType125 typedef typename Types::template apply<int> dependent_name_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}126 typedef typename T::template apply<Types> dependent_name_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}127 128 // ObjCObjectType is uninteresting129 // ObjCInterfaceType is uninteresting130 // ObjCObjectPointerType is uninteresting131};132 133// FIXME: Test for unexpanded parameter packs in each of the expression nodes.134template<int ...Values>135void test_unexpanded_in_exprs() {136 // PredefinedExpr is uninteresting137 // DeclRefExpr138 Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}139 // IntegerLiteral is uninteresting140 // FloatingLiteral is uninteresting141 // ImaginaryLiteral is uninteresting142 // StringLiteral is uninteresting143 // CharacterLiteral is uninteresting144 (Values); // expected-error{{expression contains unexpanded parameter pack 'Values'}}145 // UnaryOperator146 -Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}147 // OffsetOfExpr148 struct OffsetMe {149 int array[17];150 };151 __builtin_offsetof(OffsetMe, array[Values]); // expected-error{{expression contains unexpanded parameter pack 'Values'}}152 // FIXME: continue this...153}154 155template<typename ... Types>156void TestPPNameFunc(int i) {157 f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}158}159 160template<typename T, template<class> class ...Meta>161struct TestUnexpandedTTP {162 typedef tuple<typename Meta<T>::type> type; // expected-error{{declaration type contains unexpanded parameter pack 'Meta'}}163};164 165// Test for unexpanded parameter packs in declarations.166template<typename T, typename... Types>167// FIXME: this should test that the diagnostic reads "type contains..."168struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}169 void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}170#if __cplusplus < 201703L171 void member_function () throw(Types); // expected-error{{exception type contains unexpanded parameter pack 'Types'}}172#endif173 void member_function2() noexcept(Types()); // expected-error{{expression contains unexpanded parameter pack 'Types'}}174 operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}175 Types data_member; // expected-error{{data member type contains unexpanded parameter pack 'Types'}}176 static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}177 unsigned bit_field : static_cast<Types>(0); // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}178 static_assert(static_cast<Types>(0), "Boom"); // expected-error{{static assertion contains unexpanded parameter pack 'Types'}}179 180 enum E0 : Types { // expected-error{{fixed underlying type contains unexpanded parameter pack 'Types'}}181 EnumValue = static_cast<Types>(0) // expected-error{{enumerator value contains unexpanded parameter pack 'Types'}}182 };183 184 using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}185 using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}186 using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}187 188 friend class Types::foo; // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}189 friend void friend_func(Types); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}190 friend void Types::other_friend_func(int); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}191 192 void test_initializers() {193 T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}194 T direct_init(0, static_cast<Types>(0)); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}195 T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}196 }197 198 T in_class_member_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}199 TestUnexpandedDecls() :200 Types(static_cast<Types>(0)), // expected-error{{initializer contains unexpanded parameter pack 'Types'}}201 Types(static_cast<Types>(0))...,202 in_class_member_init(static_cast<Types>(0)) {} // expected-error{{initializer contains unexpanded parameter pack 'Types'}}203 204 void default_function_args(T = static_cast<Types>(0)); // expected-error{{default argument contains unexpanded parameter pack 'Types'}}205 206 template<typename = Types*> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}207 struct default_template_args_1;208 template<int = static_cast<Types>(0)> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}209 struct default_template_args_2;210 template<template<typename> class = Types::template apply> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}211 struct default_template_args_3;212 213 template<Types value> // expected-error{{non-type template parameter type contains unexpanded parameter pack 'Types'}}214 struct non_type_template_param_type;215 216 void decls_in_stmts() {217 Types t; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}218 for (Types *t = 0; ; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}219 for (; Types *t = 0; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}220 T a[] = { T(), T(), T() };221 for (Types t : a) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}222 switch(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}223 while(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}224 if (Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}225 try {226 } catch (Types*) { // expected-error{{exception type contains unexpanded parameter pack 'Types'}}227 }228 }229};230 231// FIXME: Test for unexpanded parameter packs in each of the statements.232struct X {233 void f(int, int);234 template<typename ...Types>235 void f(Types...);236};237 238namespace std {239 class type_info;240}241 242typedef struct _GUID {243 unsigned long Data1;244 unsigned short Data2;245 unsigned short Data3;246 unsigned char Data4[ 8 ];247} GUID;248 249template<typename T, typename ...Types>250void test_unexpanded_exprs(Types ...values) {251 // CXXOperatorCallExpr252 (void)(values + 0); // expected-error{{expression contains unexpanded parameter pack 'values'}}253 (void)(0 + values); // expected-error{{expression contains unexpanded parameter pack 'values'}}254 255 // CXXMemberCallExpr256 values.f(); // expected-error{{expression contains unexpanded parameter pack 'values'}}257 X x;258 x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}259 x.Types::f(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}260 x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}261 262 // CXXStaticCastExpr263 (void)static_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}264 265 // CXXDynamicCastExpr266 (void)dynamic_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}267 268 // CXXReinterpretCastExpr269 (void)reinterpret_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}270 271 // CXXConstCastExpr272 (void)const_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}273 274 // CXXTypeidExpr275 (void)typeid(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}276 (void)typeid(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}277 278 // CXXUuidofExpr279 (void)__uuidof(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}280 (void)__uuidof(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}281 282 // CXXThisExpr is uninteresting283 284 // CXXThrowExpr285 throw Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}286 throw values; // expected-error{{expression contains unexpanded parameter pack 'values'}}287 288 // CXXDefaultArgExpr is uninteresting289 290 // CXXBindTemporaryExpr is uninteresting291 292 // CXXConstructExpr is uninteresting293 294 // CXXFunctionalCastExpr295 (void)Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}296 297 // CXXTemporaryObjectExpr298 (void)X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}299 300 // CXXScalarValueInitExpr is uninteresting301 302 // CXXNewExpr303 (void)new Types; // expected-error{{expression contains unexpanded parameter pack 'Types'}}304 (void)new X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}305 (void)new (values) X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}306 (void)new X [values]; // expected-error{{expression contains unexpanded parameter pack 'values'}}307 308 // CXXDeleteExpr309 delete values; // expected-error{{expression contains unexpanded parameter pack 'values'}}310 delete [] values; // expected-error{{expression contains unexpanded parameter pack 'values'}}311 312 // CXXPseudoDestructorExpr313 T t;314 values.~T(); // expected-error{{expression contains unexpanded parameter pack 'values'}}315 t.~Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}316 t.Types::~T(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}317 318 // Unary TypeTraitExpr319 __is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}320 321 // Binary TypeTraitExpr322 __is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}323 __is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}324 325 // UnresolvedLookupExpr326 test_unexpanded_exprs(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}327 test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}328 329 // DependentScopeDeclRefExpr330 Types::test_unexpanded_exprs(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}331 T::template test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}332 333 // CXXUnresolvedConstructExpr334 Types(5); // expected-error{{expression contains unexpanded parameter pack 'Types'}}335 336 // CXXDependentScopeMemberExpr337 values.foo(); // expected-error{{expression contains unexpanded parameter pack 'values'}}338 t.foo(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}339 340 // FIXME: There's an evil ambiguity here, because we don't know if341 // Types refers to the template type parameter pack in scope or a342 // non-pack member.343 // t.Types::foo();344 345 t.template foo<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}346 347 // UnresolvedMemberExpr348 x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}349 x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}350 351 // CXXNoexceptExpr352 noexcept(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}353 354 // PackExpansionExpr is uninteresting355 // SizeOfPackExpr is uninteresting356 357 // FIXME: Objective-C expressions will need to go elsewhere358 359 for (auto t : values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}}360 361 switch (values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}}362 switch (0) { case 0: case values: ; } // expected-error{{expression contains unexpanded parameter pack 'values'}}363 364 do { } while (values); // expected-error{{expression contains unexpanded parameter pack 'values'}}365 366test:367 goto *values; // expected-error{{expression contains unexpanded parameter pack 'values'}}368 369 void f(int arg = values); // expected-error{{default argument contains unexpanded parameter pack 'values'}}370}371 372// Test unexpanded parameter packs in partial/explicit specializations.373namespace Specializations {374 template<typename T, typename... Ts>375 struct PrimaryClass;376 template<typename... Ts>377 struct PrimaryClass<Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}378 379 template<typename T, typename... Ts>380 void PrimaryFunction();381 template<typename T, typename... Ts>382 void PrimaryFunction<Ts>(); // expected-error{{function template partial specialization is not allowed}}383 384#if __cplusplus >= 201402L385 template<typename T, typename... Ts>386 constexpr int PrimaryVar = 0;387 template<typename... Ts>388 constexpr int PrimaryVar<Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}389#endif390 391 template<typename... Ts>392 struct OuterClass {393 template<typename... Us>394 struct InnerClass;395 template<>396 struct InnerClass<Ts>; // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}397 template<typename U>398 struct InnerClass<U, Ts>; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}399 400 template<typename... Us>401 void InnerFunction();402 template<>403 void InnerFunction<Ts>(); // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}404 405 friend void PrimaryFunction<Ts>(); // expected-error{{friend declaration contains unexpanded parameter pack 'Ts'}}406 407#if __cplusplus >= 201402L408 template<typename... Us>409 constexpr static int InnerVar = 0;410 template<>411 constexpr int InnerVar<Ts> = 0; // expected-error{{explicit specialization contains unexpanded parameter pack 'Ts'}}412 template<typename U>413 constexpr static int InnerVar<U, Ts> = 0; // expected-error{{partial specialization contains unexpanded parameter pack 'Ts'}}414#endif415 };416}417 418// Test for diagnostics in the presence of multiple unexpanded419// parameter packs.420template<typename T, typename U> struct pair;421 422template<typename ...OuterTypes>423struct MemberTemplatePPNames {424 template<typename ...InnerTypes>425 struct Inner {426 typedef pair<OuterTypes, InnerTypes>* types; // expected-error{{declaration type contains unexpanded parameter packs 'OuterTypes' and 'InnerTypes'}}427 428 template<typename ...VeryInnerTypes>429 struct VeryInner {430 typedef pair<pair<VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types; // expected-error{{declaration type contains unexpanded parameter packs 'VeryInnerTypes', 'OuterTypes', ...}}431 };432 };433};434 435// Example from working paper436namespace WorkingPaperExample {437 template<typename...> struct Tuple {};438 template<typename T1, typename T2> struct Pair {};439 440 template<class ... Args1> struct zip {441 template<class ... Args2> struct with {442 typedef Tuple<Pair<Args1, Args2> ... > type; // expected-error{{pack expansion contains parameter packs 'Args1' and 'Args2' that have different lengths (1 vs. 2)}}443 };444 };445 446 typedef zip<short, int>::with<unsigned short, unsigned>::type T1; // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>447 typedef Tuple<Pair<short, unsigned short>, Pair<int, unsigned>> T1;448 449 typedef zip<short>::with<unsigned short, unsigned>::type T2; // expected-note{{in instantiation of template class}}450 451 template<class ... Args> void f(Args...);452 template<class ... Args> void h(Args...);453 454 template<class ... Args>455 void g(Args ... args) {456 f(const_cast<const Args*>(&args)...); // OK: "Args" and "args" are expanded within f457 f(5 ...); // expected-error{{pack expansion does not contain any unexpanded parameter packs}}458 f(args); // expected-error{{expression contains unexpanded parameter pack 'args'}}459 f(h(args ...) + args ...);460 }461}462 463namespace PR16303 {464 template<int> struct A { A(int); };465 template<int...N> struct B {466 template<int...M> struct C : A<N>... {467 C() : A<N>(M)... {} // expected-error{{pack expansion contains parameter packs 'N' and 'M' that have different lengths (2 vs. 3)}} expected-error{{pack expansion contains parameter packs 'N' and 'M' that have different lengths (4 vs. 3)}}468 };469 };470 B<1,2>::C<4,5,6> c1; // expected-note{{in instantiation of}}471 B<1,2,3,4>::C<4,5,6> c2; // expected-note{{in instantiation of}}472}473 474namespace PR21289 {475 template<int> using T = int;476 template<typename> struct S { static const int value = 0; };477 template<typename> const int vt = 0; // cxx11-warning {{extension}}478 int f(...);479 template<int ...Ns> void g() {480 f(T<Ns>()...);481 f(S<T<Ns>>::value...);482 f(vt<T<Ns>>...);483 }484 template void g<>();485 template void g<1, 2, 3>();486}487 488template <class... Ts>489int var_expr(Ts... ts);490 491template <class... Ts>492auto a_function(Ts... ts) -> decltype(var_expr(ts...));493 494template <class T>495using partial = decltype(a_function<int, T>);496 497int use_partial() { partial<char> n; }498 499namespace PR26017 {500template <class T>501struct Foo {};502template <class... Ts>503using FooAlias = Foo<void(Ts...)>;504 505template <class... Ts>506using FooAliasAlias = FooAlias<Ts..., Ts...>;507 508template <class... Ts>509void bar(const FooAlias<Ts...> &) {}510 511int fn() {512 FooAlias<> a;513 bar(a);514 515 FooAlias<int> b;516 bar(b);517}518}519 520namespace GH58452 {521template <typename... As> struct A {522 template <typename... Bs> using B = void(As...(Bs));523};524 525template <typename... Cs> struct C {526 template <typename... Ds> using D = typename A<Cs...>::template B<Ds...>;527};528 529using t1 = C<int, int>::template D<float, float>;530 531template <typename A, typename B>532using ConditionalRewrite = B;533 534template <typename T>535using SignatureType = int;536 537template <typename... Args>538struct Type1 {539 template <typename... Params>540 using Return = SignatureType<int(ConditionalRewrite<Args, Params>...)>;541 542};543 544template <typename... Args>545struct Type2 {546 using T1 = Type1<Args...>;547 548 template <typename... Params>549 using Return = typename T1::template Return<Params...>;550 551};552 553template <typename T>554typename T::template Return<int, int> InvokeMethod() {555 return 3;556}557 558int Function1() {559 return InvokeMethod<Type2<int, int>>();560}561}562