[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 29 16:16:36 PDT 2024


================
@@ -0,0 +1,316 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++23 -verify %s
+
+namespace test1 {
+  template<typename T> struct Base {
+    template<typename V = T> requires true
+    Base(T);
+  };
+
+  template<typename T> struct InheritsCtors : public Base<T> {
+    using Base<T>::Base;
+  };
+
+  InheritsCtors inheritsCtors(1);
+  static_assert(__is_same(InheritsCtors<int>, decltype(inheritsCtors)));
+
+  template<typename T> struct DoesNotInheritCtors : public Base<T> {}; // expected-note {{candidate template ignored: could not match 'DoesNotInheritCtors<T>' against 'int'}} \
+                                                                       // expected-note 3{{implicit deduction guide declared as}} \
+                                                                       // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \
+                                                                       // expected-note {{candidate template ignored: could not match 'Base<T>' against 'int'}}
+  DoesNotInheritCtors doesNotInheritCtors(100); // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
+
+  template<typename T> struct InheritsSecond : public Base<T> {
+    using Base<T>::Base;
+  };
+
+  InheritsSecond inheritsSecond('a');
+  static_assert(__is_same(InheritsSecond<char>, decltype(inheritsSecond)));
+
+  template<typename T> struct NonTemplateDGuideBase {
+    NonTemplateDGuideBase(T); // expected-note {{generated from 'NonTemplateDGuideBase<T>' constructor}}
+  };
+  NonTemplateDGuideBase(int) -> NonTemplateDGuideBase<char>;
+  NonTemplateDGuideBase(const char *) -> NonTemplateDGuideBase<const char *>;
+
+  template<typename T>
+  concept NoPointers = !requires (T t) { *t; };
+
+  template<NoPointers T>
+  struct NonTemplateDGuideDerived : public NonTemplateDGuideBase<T> { // expected-note {{candidate template ignored: could not match 'NonTemplateDGuideDerived<T>' against 'const char *'}} \
+                                                                      // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \
+                                                                      // expected-note 2{{implicit deduction guide declared as }}
+    using NonTemplateDGuideBase<T>::NonTemplateDGuideBase; // expected-note {{candidate function not viable: no known conversion from 'const char[1]' to 'int' for 1st argument}} \
+                                                           // expected-note {{candidate template ignored: could not deduce template arguments for 'NonTemplateDGuideDerived<T>' from 'NonTemplateDGuideBase<T>' [with T = const char *]}} \
+                                                           // expected-note {{implicit deduction guide declared as 'template <NoPointers<> T> NonTemplateDGuideDerived(T) -> typename __ctad_CC_NonTemplateDGuideBase_to_NonTemplateDGuideDerived_0<NonTemplateDGuideBase<T>>::type'}} \
+                                                           // expected-note {{candidate template ignored: could not match 'NonTemplateDGuideBase<T>' against 'const char *'}} \
+                                                           // expected-note {{implicit deduction guide declared as 'template <NoPointers<> T> NonTemplateDGuideDerived(NonTemplateDGuideBase<T>) -> typename __ctad_CC_NonTemplateDGuideBase_to_NonTemplateDGuideDerived_0<NonTemplateDGuideBase<T>>::type'}}
+  };
+
+  NonTemplateDGuideDerived ntdg(1);
+  static_assert(__is_same(NonTemplateDGuideDerived<char>, decltype(ntdg)));
+
+  NonTemplateDGuideDerived ntdg_char(""); // expected-error {{no viable constructor or deduction guide for deduction of template arguments}}
+
+  template<typename T>
+  struct ExplicitBase {
+    template<typename V>
+    ExplicitBase(V);
+  };
+
+  template<typename T>
+  ExplicitBase(T) -> ExplicitBase<T>;
+
+  template<NoPointers T>
+  struct ExplicitDerived : public ExplicitBase<T> { // expected-note {{candidate template ignored: could not match 'ExplicitDerived<T>' against 'const char *'}} \
+                                                    // expected-note {{candidate function template not viable: requires 0 arguments, but 1 was provided}} \
+                                                    // expected-note 2{{implicit deduction guide declared as }}
+
+    using ExplicitBase<T>::ExplicitBase; // expected-note {{candidate template ignored: couldn't infer template argument 'T'}} \
+                                         // expected-note {{implicit deduction guide declared as 'template <NoPointers<> T, typename V> ExplicitDerived(V) -> typename __ctad_CC_ExplicitBase_to_ExplicitDerived_0<ExplicitBase<T>>::type'}} \
+                                         // expected-note {{candidate template ignored: could not match 'ExplicitBase<T>' against 'const char *'}} \
+                                         // expected-note {{candidate template ignored: could not deduce template arguments for 'ExplicitDerived<T>' from 'ExplicitBase<T>' [with T = const char *]}} \
+                                         // expected-note {{implicit deduction guide declared as 'template <NoPointers<> T> ExplicitDerived(ExplicitBase<T>) -> typename __ctad_CC_ExplicitBase_to_ExplicitDerived_0<ExplicitBase<T>>::type'}}
----------------
antangelo wrote:

By `<implicit deduction guide for X inherited from Y>` do you mean to show the declaration for the original deduction guide on the base instead of the transformed guide on the derived class?

https://github.com/llvm/llvm-project/pull/98788


More information about the cfe-commits mailing list