概念可以替换模板关键字的所有其他实例吗?

时间:2015-09-24 04:01:30

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

可以使用C ++概念替换关键字template的所有外观 (除了概念自己的声明)?

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

为了使我的问题简短, 常规模板声明可以做什么,概念+ constexpr的采用不能取代?

2 个答案:

答案 0 :(得分:6)

显式实例化仍然需要

template

template some_class<int>;

消除依赖成员模板的歧义

obj.template fun<T>();

答案 1 :(得分:4)

你的前提是有点负荷。虽然可能通过概念介绍来转换模板的旧语法(对于函数,类,变量或别名模板都是一样的),但在许多情况下这样做是人为的并且传递了接力棒。以经典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的合理,概念启用的声明看起来如此(因为我们没有标准概念,但我在这里使用虚构的概念和特征,专注于原理):< / p>

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-clauses中出现的元素肯定是可重用的(迭代器引用类型和std::result_of_t确实已经在使用中)。

这个相对简单的例子说明了为什么概念介绍根本不适用于所有地方。一些需求元素涉及我想称为第三方类型,即iterator_reference_t<…>result_of_t<…>,而一些输入类型同时涉及多个关系(例如,It出现在IteratorCallable)。

否则,即当所有论证类型之间只有一个关系而且只有它们时,如果该关系合理地表达了意图并且最好是可重用的;然后概念介绍可能会有他们的位置。 (带有概念介绍的缩略模板虽然扩大了这个应用领域。)