当使用透明的std函数对象时,我们还需要写空的尖括号吗
Do we still need to write the empty angle brackets when using transparent std function objects?
通过类模板参数推导,我们可以编写:
std::less Fn;
然而,G++8.2拒绝了这个代码:
#include <algorithm>
#include <vector>
#include <functional>
int main()
{
std::vector v= { 1, 3, 2, 7, 5, 4 };
std::sort(v.begin(),v.end(),std::greater());
}
发出以下错误:
error: cannot deduce template arguments for 'greater' from ()
Clang++7.0和MSVC 15.8.0在没有警告的情况下编译它。哪个编译器是对的?
GCC错误。已经有一个错误报告。
[dcl.type.simple]/2表示:
形式为
typename
opt嵌套名称说明符>opt模板名称的类型说明符是推导类类型([dcl.type.class.dexecte](的占位符。
并且[dcl.type.class.dexecute]/2说:
推导类类型的占位符也可以用于新表达式的类型id中的type说明符seq,在显式类型转换(函数表示法(中用作简单类型说明符([expr.type.conv](,或在模板参数的参数声明中作为类型说明符。推导类类型的占位符不应出现在任何其他上下文中。
允许这样的使用。
[temp.arg]/4描述了语法错误,即需要模板id,但没有<>
。然而,此处std::greater
未解析为模板id,因此该段不适用。
Clang和MSVC是正确的。由于隐式生成的推导指南(自C++17以来(和默认模板参数的组合效应,这应该是很好的形式。
(重点矿井(
当函数样式转换或变量声明使用名称时没有参数列表作为类型的主类模板C的说明符,推导过程如下:
- 如果定义了C,则对于命名的主模板(如果定义了它(中声明的每个构造函数(或构造函数模板(Ci构建函数模板Fi,使得
- Fi的模板参数是C的模板参数,后面是模板参数(如果Ci是构造函数模板(Ci的(也包括默认模板参数(
- Fi的函数参数是构造函数参数
- Fi的返回类型是C,后跟<>中包含的类模板的模板参数
- 如果C没有定义或没有声明任何构造函数,则会添加一个额外的虚构函数模板,该模板如上所述从一个假设的构造函数C((
- 在任何情况下,都会添加一个从假设构造函数C(C(派生的附加虚构函数模板,称为副本扣除候选者
然后执行模板参数推导和重载解析对于假设类类型的虚构对象的初始化,其构造函数签名与指南匹配(返回类型除外(为了形成重载集,初始化器是由类模板参数推导所在的上下文提供执行,除了列表初始化的第一阶段如果初始值设定项列表由类型为(可能cv限定(U,其中U是C的专业化或派生的类来自C.的一个专业
这些虚构的构造函数是假设的公共成员类类型。如果指南是由明确的构造函数。如果过载解析失败,则表示程序格式不正确。否则,所选F模板专用化的返回类型成为推导出的类模板专门化。
给定std::greater()
,应用隐式生成的推导指南,最后选择附加的虚构函数。作为重载解析的结果,应用默认参数void
,则推导出的类型将为void
。这意味着std::greater()
应该与写入std::greater<void>()
或std::greater<>()
相同。
BTW:Gcc不使用std::greater()
编译,但std::greater{}
或std::greater g;
可以,这可能是Gcc的错误
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 当使用透明的std函数对象时,我们还需要写空的尖括号吗
- 是否可以子类 std::unique_ptr 透明地应用自定义删除器
- 有没有一种透明的方式来在 std 容器中使用unique_ptr
- 为什么没有透明的C++1x std::map::at?
- 透明地配置std::function / lambda回调