提问人:ByteEater 提问时间:11/14/2023 更新时间:11/14/2023 访问量:69
在 lambda 参数中使用 type_identity_t
Use type_identity_t in a lambda argument
问:
我正在尝试在表达式中重新实现 Logan Smith 的 Cursed C++ Casts。我的方法是将匿名函数与:implicit_cast
type_identity_t
#include <iostream>
using namespace std;
int main() {
int i = 1;
long j = 4;
cout << max(j, []<class T>(type_identity_t<T> x) -> T { return x; }(i));
}
但它不起作用。编译器(gcc 13.2)抱怨:
<source>: In function 'int main()':
<source>:6:70: error: no match for call to '(main()::<lambda(std::type_identity_t<T>)>) (int&)'
6 | cout << max(j, []<class T>(type_identity_t<T> x) -> T { return x; }(i));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
<source>:6:18: note: candidate: 'template<class T> main()::<lambda(std::type_identity_t<T>)>'
6 | cout << max(j, []<class T>(type_identity_t<T> x) -> T { return x; }(i));
| ^
<source>:6:18: note: template argument deduction/substitution failed:
<source>:6:70: note: couldn't deduce template parameter 'T'
6 | cout << max(j, []<class T>(type_identity_t<T> x) -> T { return x; }(i));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
可以挽救吗?或者我应该改用其他方法?
答:
2赞
user17732522
11/14/2023
#1
正如视频所解释的那样,必须使用指定目标类型的显式模板参数来调用它。您的 lambda 调用缺少这一点。重点是让它不会被自动推断出来。它用于强制用户显式指定模板参数。它没有任何其他功能影响。implicit_cast
type_identity_t<T>
T
要使用显式模板参数调用 lambda,您需要编写
[]<class T>(type_identity_t<T> x) -> T { return x; }.operator()</*target type*/>(i)
评论
0赞
ByteEater
11/14/2023
或者我可以写.我正在寻找以某种方式推断目标类型的最通用的可能方法,以便在其他地方发生类型更改时代码继续工作。decltype(j){i}
1赞
user17732522
11/14/2023
@ByteEater是不一样的,因为它是直接列表初始化,而不是隐式转换。如果您实际上并不关心所使用的特定初始化形式,那么就足够了。Braced-init-lists 不是从中推导出来的。但是,如果您切换 和 的类型,这将不相同,因为这样它就变成了缩小转换,通常允许作为隐式转换,但具体而言,在列表初始化中不允许。decltype(j){i}
{i}
i
j
0赞
ByteEater
11/14/2023
你是对的,这等效于这种特定情况,但你的 with 保留了 的关键特征。但它需要提及目标类型。我想要指出的是,结合您的代码:..operator()
implicit_cast
[]<class T>(type_identity_t<T> x) -> T { return x; }.operator()<decltype(j)>(i)
1赞
user17732522
11/14/2023
@ByteEater 是的,这有效,但如果您要追求普遍性,那么请注意所呈现的内容也有问题。例如,它可能会进行简单的隐式转换无法执行的额外构造函数调用。implicit_cast
1赞
user17732522
11/15/2023
@ByteEater 这是预期的,但也会有一个对返回值的移动/复制构造函数调用。因此,即使函数参数的正常隐式转换有效,它也不适用于不可移动的类型。
下一个:对于每个单元格值:重复一系列值
评论