`struct decay<T, R(A..., ...)>` 的含义是什么?

6
template <typename T, typename R, typename ...A>
struct decay<T, R(A..., ...)> { using type = R(*)(A..., ...); };

这个的确切含义是什么?我需要一些帮助~


1
你在哪里看到那段代码的?它看起来很像是用于实现std::decay的合理代码,但没有理由使用T... 我的第一个猜测是你复制错了。 - Yakk - Adam Nevraumont
@Yakk:这段代码来自boost::hana。 - John Smith
1
Aha: http://www.boost.org/doc/libs/1_62_0/libs/hana/doc/html/structboost_1_1hana_1_1detail_1_1decay.html 这是一种优化。这解释了原本毫无意义的设计;他们正在解决模板实例化效率低下的问题。 - Yakk - Adam Nevraumont
1
所以我的下一个问题是:这是元编程库的详细命名空间内。因此,它并不是真正意图易于理解的。你觉得它令人困惑的是什么?你知道什么是模板吗?模板特化?特征类?你知道std::decay是什么吗?你理解函数参数类型衰减的概念吗?“这的确意味着什么”不是一个有用的问题。请更具体一些。 - Yakk - Adam Nevraumont
@Yakk:抱歉。我想知道上面的代码与struct decay<T, R(A...)>有何不同。 - John Smith
2个回答

7
int foo(int);
int bar(int, ...);

这是两个不同的函数。 foo 的类型为 int(int)bar 的类型为 int(int,...)... 是 C 风格的可变参数列表,不要与使用 ... 的变长模板参数混淆。
template <typename T, typename R, typename ...A>
struct decay<T, R(A..., ...)> { using type = R(*)(A..., ...); };

这是在boost::hana中实现std :: decay优化版本的一部分。typename T和T部分是该优化的一部分,但不影响其功能。
这是一个专门匹配R(A…,…)的特化版本,其中A…和R从函数签名中推导得出。
如果将double(int, char, ...)作为第二个参数传递给此hana::details::decay,则R将是double,A…将是int,char。而“...”将“匹配C风格的可变参数”。
这种特定的专业化旨在将以C样式varargs结尾的函数签名映射到指向相同签名的指针。因此,它将double (int,char,...)映射到double(*)(int,char,...)。
C风格的varargs与模板variardic参数不同,它们比其先存在。

非常感谢。这就是我想知道的。 - John Smith

6
这个专业化是将函数类型衰减为相应的指向函数类型的指针之一,这反映了函数lvalues衰减为函数指针prvalues的方式。
这个特定的专业化用于变参函数(其参数列表以省略号结尾,因此它接受与任何参数都不匹配的参数)。

1
template <typename R, typename ...A>struct decay<R(A..., ...)> { using type = R(*)(A..., ...); };decay 的一个特化版本,用于捕获特定类型的函数签名。我不明白为什么你会有一个两个参数版本的decay,然后忽略第一个参数。 - Yakk - Adam Nevraumont
1
这是来自details命名空间的一个优化技巧。这就解释了为什么它作为代码几乎没有意义。 - Yakk - Adam Nevraumont
@JohnSmith,这个专业化是为了带有可变参数数量的函数而设计的,比如int printf(const char *,...)。在这段代码中:R(A..., ...);,第一个省略号展开了参数包A,而第二个省略号则作为函数类型的一部分保留。 - HolyBlackCat
@KerrekSB 这个decay两个参数,而不是一个。这就是为什么会让人困惑的原因。结果证明它是hana::details中的一种优化。我猜测它保留了T,以生成稍微更好的错误消息,并且他们发现这(以某种方式)并没有导致编译开销。我很惊讶第一个参数没有导致额外的编译成本,但我不是模板微观优化方面的专家。 - Yakk - Adam Nevraumont
@KerrekSB:抱歉。我想知道上面的代码与template <typename T, typename R, typename ...A> struct decay<T, R(A...)> { using type = R(*)(A...); };有什么不同。 - John Smith
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接