const_forward在C++中的可选实现中做什么?
What does const_forward do in optional implementation in C++?
嗨,我正在这里查看std::optional
实现之一,我发现这个代码片段让我感到困惑:
// workaround: std utility functions aren't constexpr yet
template <class T> inline constexpr T&& constexpr_forward(typename
std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
所以我不以以下方式理解这一点:
typename
在这里做什么?只是声明以下部分是一个类型?- 为什么我们需要
std::remove_reference
?我们不是在type&
部分添加了引用吗? - "std 效用函数还不是 constexpr"是什么意思?这个函数如何使它们变得通俗?它的身体只是一个
static_cast
. - 这个函数在许多构造函数中使用,它看起来像这样:
template <class... Args> constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
,那么它在这里对 args 有什么作用?
多谢。
template <class T> inline constexpr T&& constexpr_forward(typename
std::remove_reference<T>::type& t) noexcept
{
return static_cast<T&&>(t);
}
typename
在这里做什么?只是声明以下部分是一个类型?
std::remove_reference<T>::type
是一个依赖于模板参数T
的依赖类型,因此我们需要typename
告诉编译器我们正在尝试使用依赖名称,
- 为什么我们需要
std::remove_reference
?我们不是在type&
部分添加了引用吗?
如果您检查此实用程序函数的示例用法,如下所示
....
template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
...
您可以看到,可变参数 fowarding 引用类型用作显式模板参数来constexpr_foward<Args>(args)...
。这将保留类型的值类别。当任何参数是引用时,就好像我们用constexpr_forward<Arg01&>(arg01)
调用该实用程序函数一样。该模板的安装将是
inline constexpr Arg01&&& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&&&>(t);
}
通过引用折叠规则,我们有
inline constexpr Arg01& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&>(t);
}
实际上,删除引用应该是多余的(阅读有关引用折叠的信息(;
- "std 效用函数还不是 constexpr"是什么意思?这个函数如何使它们变得通俗?它的身体只是一个
static_cast
.
它只不过是在函数和构造函数constexpr
中转发一个非constexpr
函数。
- 这个函数在许多构造函数中使用,它看起来像这样:
template <class... Args> constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
,那么它在这里对参数有什么作用?
基本上如上所述..
您可能需要返回一步并做更多的阅读,此代码相当高级,您的问题表明您尚未阅读其中的一些内容。我会推荐斯科特·迈耶斯(Scott Meyers(的《现代有效C++》。至于您的具体问题:
- 是的,有必要使用
typename
,因为我们正在处理模板类的成员,这是一个依赖类型。把它想象成向编译器保证这个东西确实是一个类型,在编译器可以验证它之前的某个时刻(因为模板尚未实例化,只是定义,所以它不知道T
是什么(。 - 与大多数模板函数不同,
std::forward
的想法是显式指定模板参数以使其正常工作。此形式禁用了在这种情况下可取的类型推导(罕见(。请注意,删除引用并重新添加它并不等同于什么都不执行,就好像它不是一开始的引用,它仍然以一个引用结束。这就是目标;始终采用左值引用。 - 这只是意味着它们没有被标记为
constexpr
.函数可以在常量表达式中使用,如果它被标记为constexpr
。并非所有功能都可以标记为constexpr
,存在限制。标准库函数std::forward
可以是 constexpr,但事实并非如此。此函数只是一种解决方法。 - 这基本上等同于
std::forward
,所以最好用谷歌搜索一下并阅读它,因为这不是一件微不足道的事情(我提到的书谈到了它(。基本上这个想法是,一旦你有一个接受一组参数的函数,假设它想将这些参数转发到其他地方。问题是所有符号名称(在本例中为args
(都被视为左值(即使它们是右值引用......正如我所说,这令人困惑,类型与值类别(。但是,如果用户传入了任何临时函数,那么我们希望将其正确转发(即作为临时函数(到下一个函数。std::forward
确保作为右值传入的内容被强制转换为右值引用,并且可以由内部函数正确使用。
我希望这有所帮助。同样,您需要花一些时间阅读以更深入地了解价值类别,并重新引用以完全消化它。
相关文章:
- 实现无开销push_back的最佳方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 什么是现实中的"endl"(或任何输出操纵器)?它是如何实现的,它如何与操作员<<一起工
- cv::Normalise() 中的 L2_NORM 和 NORM_MINMAX 实现有什么区别?
- "in-situ without memory allocation" 字符串的愚蠢实现意味着什么?
- 私有在函数定义/实现的返回值范围内是什么意思 (c++)?
- 在 c++ 或 python 中生成一个体面的视差图以在 Raspberry Pi 上实现的最佳方法(算法或函数)是什么
- 在C++中将内部类实现为具有名称空间的独立类有什么好处
- 在 C++17 中实现迭代器和const_iterator的正确方法是什么?
- 它叫什么以及如何实现此行为?
- 十进制到二进制的实现不能完全适用于我大学的检查器。问题或提示可能是什么
- 不实现父类的虚拟方法有什么风险
- const_forward在C++中的可选实现中做什么?
- 在这种情况下,有什么正确的方法可以实现锁定吗?
- 实现此自定义priority_queue的正确方法是什么
- 什么更有效率?在重载函数中或通过在基类函数中检查对象类型来实现
- 我需要一个像堆栈一样的数据结构,但具有随机访问,但是,我应该实现什么
- 这C++代码试图实现什么
- 在linux中调用bg时应该实现什么状态