C++ 概念能否用于替换关键字的所有外观template
(除了概念自己的声明)?
我很好奇是否有任何理由仍然需要将关键字template
用于其他语言结构,例如模板化类或模板化函数。我能想到的唯一例外是模板化类型别名。使用模板进行编译时间计算将可以通过constexpr
函数替换。
为了让我的问题保持简短,
常规模板声明可以做什么,采用概念 + constexpr 无法替代?
C++ 概念能否用于替换关键字的所有外观template
(除了概念自己的声明)?
我很好奇是否有任何理由仍然需要将关键字template
用于其他语言结构,例如模板化类或模板化函数。我能想到的唯一例外是模板化类型别名。使用模板进行编译时间计算将可以通过constexpr
函数替换。
为了让我的问题保持简短,
常规模板声明可以做什么,采用概念 + constexpr 无法替代?
template
显式实例化仍然需要
template some_class<int>;
并消除依赖成员模板的歧义
obj.template fun<T>();
你的前提有点负荷。虽然可以通过概念介绍来转换模板的旧语法(对于函数、类、变量或别名模板都一样),但在许多情况下这样做是人为的并且传递了接力棒。以经典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
伪概念在其他地方可重用的可能性有多大,它对程序员有什么帮助?此声明不会为您提供旧信息的新信息。我承认,假设这个伪概念被正确编写,程序员应该从改进的诊断/重载解决方案中受益。
相反,我希望一个明智的、支持概念的声明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<…>
and result_of_t<…>
,而一些输入类型同时涉及多个关系(例如It
出现在Iterator
and中Callable
)。
否则,即当所有参数类型之间只有一种关系并且只有它们之间存在一种关系时,并且该关系是否可以合理地表达意图并且最好是可重用的;那么概念介绍可能会占有一席之地。(不过,一个带有概念介绍的缩写模板进一步拓宽了这个应用领域。)