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

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 17 02:01:07 PDT 2024


hokein wrote:

Thanks for implementing it! 

I haven't looked into the implementation details yet.
Before doing so, I want to ensure I understand the standard correctly (the standard's wording is a bit hard to follow).

Per C++ [over.match.class.deduct#1.10](https://eel.is/c++draft/over.match.class.deduct#1.10):

> In addition, if C is defined and inherits constructors ([[namespace.udecl]](https://eel.is/c++draft/namespace.udecl)) from a direct base class denoted in the [base-specifier-list](https://eel.is/c++draft/class.derived.general#nt:base-specifier-list) by a [class-or-decltype](https://eel.is/c++draft/class.derived.general#nt:class-or-decltype) B, let A be an alias template whose template parameter list is that of C and whose [defining-type-id](https://eel.is/c++draft/dcl.name#nt:defining-type-id) is B[.](https://eel.is/c++draft/over.match.class.deduct#1.sentence-7) If A is a deducible template ([[dcl.type.simple]](https://eel.is/c++draft/dcl.type.simple)), the set contains the guides of A with the return type R of each guide replaced with typename CC<R>​::​type given a class template
template <typename> class CC;
whose primary template is not defined and with a single partial specialization whose template parameter list is that of A and whose template argument list is a specialization of A with the template argument list of A ([[temp.dep.type]](https://eel.is/c++draft/temp.dep.type)) having a member typedef type designating a template specialization with the template argument list of A but with C as the template[.](https://eel.is/c++draft/over.match.class.deduct#1.sentence-8)

Let's use the following example to illustrate:

```cpp
template <typename T1> struct B {
  B(T1);
};
template <typename T2> struct C : public B<T2> {
  using B<T2>::B;
};
```

Here, `C` is the struct `C`, and `B` is `B<T2>`.


### Steps:

1. **Find the inherited constructor for class `C`:** `B(T1)`.

2. **Synthesize an alias template `A`:** `template<typename T2> using A = B<T2>;`

3. **Check if `A` is a deducible template per https://eel.is/c++draft/dcl.type.simple#3:** here A is deducible

4. **Synthesize the deduction guide for `A`:** the one we have interests is `auto (T2) -> B(T2)`

5.  **Replace the return type with `CC<B<T2>>::type`:**

    ```cpp
    template <typename> class CC;

    template <typename T2>
    class CC<B<T2>> {
    public:
        typedef C<T2> type;
    };
    ```

The we get the final deduction guide for C: `auto (T2) -> CC<B<T2>>::type`;

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


More information about the cfe-commits mailing list