代码之家  ›  专栏  ›  技术社区  ›  W.F.

用户定义的扣除指南是否包含模板参数作为指南标准的模板

  •  12
  • W.F.  · 技术社区  · 6 年前

    出身背景

    guarantees of deduction guides usage in case of template template parameters . 我真的很惊讶,当巴里改变了他的答案,以确认符合标准的守则。我的惊讶并不是因为演绎指南可以应用于模板参数,而是因为标准部分符合这一要求,即 [temp.param]/3 :

    类型参数 其标识符不在省略号之后,则将其标识符定义为 类型定义名 (如果声明没有 template 模板名称 (如果用 样板 )在模板声明的范围内。

    [temp.deduct.guide]/1 simple-template-id 将允许创建一个通用的扣除指南,接受任何模板。

    实例

    #include <string>
    
    template <class T>
    struct Foo {
       Foo(T) { }
    };
    
    template <template <class> class TT>
    TT(const char *) -> TT<std::string>;
    
    int main() {
        Foo foo("abc");
    }
    

    代码导致 gcc 由于内部错误而崩溃并导致编译错误 clang 说该代码实际上应该在C++中被允许,但认为当前的措辞确实使其符合要求。我是否遗漏了一些禁止代码的重要规则?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Johannes Schaub - litb    6 年前

    你的例子

    冒着出错的风险,我将引用一个现已删除的答案

    如果我没有弄错的话,这与[temp.Decrete.guide]p3相冲突:

    简单模板id应命名为类模板专门化。

    TT<std::string> 没有命名类模板专门化,并且您的代码格式不正确。

    TT 是一个模板 类型参数 从技术上讲和构造 TT<标准::字符串> 类型名称 . 如果演绎指南是一个实际的函数模板,我们会实例化它, TT<标准::字符串> 可以实例化为 这涉及到类模板专门化。它也可以指 int 如果 TT 实例化以引用适当定义的别名模板。但是,在演绎指南声明中,它还没有命名类模板专门化。

    [temp.res]p8.5.5中有一条规定,即

    否则,对于可以生成有效专门化的模板,不应发布诊断。

    那么,演绎指南的专业化会发生吗 完全 ? 我与 . 首先,它不是一个可以实例化的“模板实体”(c.f[temp]p8)。在类模板参数推导中专门使用的是一组模板,这些模板是 基于演绎指南形成 ,但不是向导自己。参见[over.match.class.Decrete]p1.4

    [...] 对于每个推导指南,都会形成一个具有以下属性的函数或函数模板:[…]

    正是这些函数模板在重载解析过程中被进一步专门化。演绎引导本身从来都不是专门化的,因此,我们可以生成一条诊断消息,用于违反规则 简单模板id 在演绎指南中没有命名类模板专门化。

    按别名模板命名(Richard的示例)

    理查德举了一个不同的例子

    template<typename T> class X { T t; };
    template<typename T> using Y = X<T*>;
    template<typename T> Y(T) -> Y<T>;
    

    在这种情况下,它更复杂,我认为这可能是允许的措辞,因为 Y<T> 姓名 专业化或仅仅 在应用重写规则之后。事实上,它可以允许争论,这似乎足以保证缺陷报告,国际海事组织。