Руководство пользователя по выводу для вложенных типов-шаблонов

Q1 : Допускаются ли определяемые пользователем руководства по дедукции в области пространства имен?

В приведенном здесь примере GCC и Clang не ведут себя одинаково:

Короче говоря, у нас есть тип, параметризованный шаблоном, с вложенным типом, который сам параметрируется шаблоном, а параметры шаблона не имеют взаимосвязи друг с другом.

      template <typename T>
struct some_type;
template <template <typename...> typename T, typename ... Ts>
struct some_type<T<Ts...>>
{
    template <typename U>
    class nested // <- nested type, where `U` as no relationship with `T<Ts...>`
    {
        U member;
    public:
        nested(U &&);
    };
};

В стандарте указывается: http://eel.is/c++draft/temp.deduct.guide#3

[...] Руководство по дедукции должно быть объявлено в той же области, что и соответствующий шаблон класса, и для шаблона класса-члена с тем же доступом. [...]

Q2 : Если нет для Q1, каков синтаксис для создания определяемого пользователем руководства по выводу для вложенного типа, когда нет связи между типом пространства имен и параметрами шаблона вложенного типа?

Я бы ожидал синтаксиса, близкого к:

      template <template <typename...> typename T, typename ... Ts>
template <typename U>
some_type<T<Ts...>>::nested<U>::nested(U&&) -> nested<U>;

Тем не мение, nested<U>это не так , как это требовалось выведенный тип ... вывести его.

Кроме того, это интерпретируется как функция с конечным возвращаемым типом. void.

      template <template <typename...> typename T, typename ... Ts>
template <typename U>
typename some_type<T<Ts...>>::template nested<U>::nested(U&&) -> nested<U>;

Спасибо за ваше время.

1 ответ

Быстрая починка

Единственный обходной путь, который я нашел, это добавить только для Clang,
который не оптимален с точки зрения ремонтопригодности.

Живой пример на godbolt или
смотрите исходники ниже.

Почему ?

  • GCC не разрешает руководство по дедукции в контексте, отличном от пространства имен, в отличие от Clang .
  • В этом контексте для Clang требуется руководство по дедукции, а для GCC — нет .

NB: на момент публикации этот ствол clang — 11.0.1, а ствол gcc — 10.2.

      #include <tuple>

template <typename T>
struct type
{
    template <typename U>
    struct nested
    {
        template <typename ... nested_Ts>
        nested(U &&, std::tuple<nested_Ts...> &&)
        {}

    };
    #if __clang__
    // here, user-defined deduction guide only for Clang
    template <typename U, typename ... Ts>
    nested(U&&, std::tuple<Ts...>&&) -> nested<U>;
    #endif
};

void instanciate_symbols()
{
    using type = type<int>;
    [[maybe_unused]] auto value = type::nested{'a', std::tuple{42, .42f}};
}
Другие вопросы по тегам