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