【问题标题】:Can concepts replace all other instances of the template keyword?概念可以替换模板关键字的所有其他实例吗?
【发布时间】:2015-09-24 04:01:30
【问题描述】:

C++ 概念能否用于替换所有出现的关键字template
(除了概念自己的声明)?

我很好奇是否还有任何理由需要将关键字template 用于其他语言结构,例如模板类或模板函数。我能想到的唯一例外是模板化类型别名。使用模板进行编译时间计算可以通过constexpr 函数替换。

为了让我的问题简短,
常规模板声明能做什么,是概念+ constexpr 无法替代的?

【问题讨论】:

  • 您能否阐明概念的含义,例如通过提供相应工作草案的链接?

标签: c++ templates template-meta-programming c++17 c++-concepts


【解决方案1】:

template 仍然需要显式实例化

template some_class<int>;

并消除依赖成员模板的歧义

obj.template fun<T>();

【讨论】:

    【解决方案2】:

    你的前提有点负荷。虽然可能通过引入概念来转换模板的旧语法(对于函数、类、变量或别名模板都一样),但在许多情况下,这样做是人为的并且传递了接力棒。以经典的std::transform函数模板为例:

    // current
    template<typename In, typename Out, typename Func>
    Out transform(In first, In last, Out out, Func func);
    

    您可以将其转换为以非常明显的方式使用概念介绍:

    TransformParameters{In, Out, Func}
    Out transform(In first, In last, Out out, Func func);
    

    正如您所说,这是相当机械的,而且毫无意义:TransformParameters 伪概念在其他任何地方可重用的可能性有多大,它对程序员有什么帮助?此声明将为您提供no旧信息的新信息。我承认,假设这个伪概念编写正确,程序员应该受益于改进的诊断/重载解决方案。

    相反,我希望std::transform 的合理、支持概念的声明看起来像这样(因为我们没有标准概念,但我在这里使用虚构的概念和特征,重点关注原则):

    template<Iterator In, Iterator Out, Value Func>
        requires
            Callable<Func, iterator_reference_t<In>>
            && AssignableFrom<
                iterator_reference_t<Out>,
                result_of_t<Func(iterator_reference_t<In>)>
            >
    Out transform(In first, In last, Out out, Func func);
    

    要求的想法反映了std::transform 具有关联表达式*out = func(*in) 的事实。此外,出现在 requires 子句中的元素当然是可重用的(迭代器引用类型和 std::result_of_t 确实已经在使用中)。

    这个相对简单的例子说明了为什么概念介绍根本不会在任何地方都起作用。一些require元素涉及我想称之为第三方类型,即iterator_reference_t&lt;…&gt;result_of_t&lt;…&gt;,而一些输入类型同时涉及多个关系(例如It出现在Iterator和@987654334中@)。

    否则,即当所有参数类型之间只有一种关系并且只有它们之间存在一种关系时,并且该关系是否可以合理地表达意图并且最好是可重用的;那么概念介绍可能会占有一席之地。 (不过,一个带有概念介绍的缩写模板进一步拓宽了这个应用领域。)

    【讨论】:

    • 但给定概念 Input_iteratorOutput_iteratorUnary_function,TS 将为其定义 requires 子句,template&lt;Input_iterator It, Output_iterator Out, Unary_function Fun&gt; transform(It first, It last, Fun fun); 将是净赢,不是吗?
    • @TemplateRex 我不关注。那仍然使用template 关键字并且没有捕获std::transform 的完整约束,这是我的论点所必需的。请记住:重要的是原则,而不是确切的概念。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 2011-06-08
    • 2018-06-13
    相关资源
    最近更新 更多