c++ - 嵌套模板类型的用户定义推导指南

标签 c++ c++17 ctad

第一季度 :命名空间范围内是否允许用户定义的推导指南?
在这里的示例中,GCC 和 Clang 不会产生相同的行为:

  • https://godbolt.org/z/8W6hznEjo

  • #include <tuple>
    
    template <typename T>
    struct some_type;
    template <template <typename...> typename T, typename ... Ts>
    struct some_type<T<Ts...>>
    {
        template <typename U>
        class nested
        {
            U member;
        public:
            nested(U &&){}
        };
    
        // non-namespace scope user-deduction-guide : OK with Clang, fix the deduction issue
        template <typename U>
        nested(U&&) -> nested<U>;
    };
    
    void func()
    {
        using pack_type = std::tuple<int, char>;
        some_type<pack_type>::nested{
            [](auto &&){}
        };
    }
    
    简而言之,我们有一个模板参数类型,嵌套类型本身就是模板参数,模板参数之间没有关系。
    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

    [...] A deduction-guide shall be declared in the same scope as the corresponding class template and, for a member class template, with the same access. [...]


    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>;
    
    谢谢你的时间。

    最佳答案

    快速解决
    我发现的唯一解决方法是添加 user-defined deduction guide仅适用于 Clang,
    这是方式次优在可维护性方面。
    Live example on godbolt ,
    或查看以下来源。
    为什么 ?

  • 海合会不允许在非命名空间上下文中使用推导指南,叮当做。
  • 叮当在这种情况下需要扣除指南,海合会

  • 注意:发布此内容时,clang trunk 为 11.0.1,gcc trunk 为 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}};
    }
    

    关于c++ - 嵌套模板类型的用户定义推导指南,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66765599/

    相关文章:

    c++ - 如何在linux下用c/c++构建igmp查询生成器

    c++ - 有什么方法可以更快地打印 2D Array 吗?

    c++ - 从引用类型在 lambda 中捕获的值的类型,不使用广义捕获

    c++ - 为什么我们不能在内联命名空间之外声明演绎指南?

    c++ - clang vs gcc - 从模板参数派生的结构的 CTAD

    c++ - 怎么了?如何更改 "sum1"顺序?

    c++ - std::cout 不适用于结构的重载 '<<' 运算符

    c++ - 在运算符表达式上下文中纠正重载解析的内置运算符候选的行为

    c++ - (C++17; Boost) CMake 找不到请求的 Boost 库

    c++ - 如何进行跨度类推导以正确执行右值数组的 CTAD?