您好我正在here查看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&
?我们没有在static_cast
部分添加引用吗?template <class... Args>
constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
。非常感谢。
答案 0 :(得分:5)
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
告诉编译器我们正在尝试使用{ {3}},
- 为什么我们需要
醇>std::remove_reference
?我们没有在type&
部分添加引用吗?
如果您在dependent-name
中查看此实用程序功能的示例用法....
template <class... Args> explicit constexpr constexpr_optional_base(in_place_t, Args&&... args)
: init_(true), storage_(constexpr_forward<Args>(args)...) {}
...
你可以看到,一个可变参与类型参考类型被用作constexpr_foward<Args>(args)...
的显式模板参数。这将保留该类型的here。当任何参数是引用时,就好像我们用constexpr_forward<Arg01&>(arg01)
调用该实用函数一样。并且该模板的实例将是
inline constexpr Arg01&&& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&&&>(t);
}
和value category,我们有
inline constexpr Arg01& constexpr_forward(Arg01& t) noexcept
{
return static_cast<Arg01&>(t);
}
实际上,删除引用应该在那里是多余的(阅读有关引用崩溃的内容);
- &#34; std实用程序功能还没有constexpr&#34;意思?这个函数如何使它们成为constexpr?它的主体只是
醇>static_cast
。
constexpr
函数和构造函数中只有reference collapsing rule非constexpr
函数。
- 此函数在许多构造函数中使用,它看起来像这样:
醇>template <class... Args> constexpr storage_t( Args&&... args ) : value_(constexpr_forward<Args>(args)...) {}
,那么它对args做了什么?
基本上如上所述..
答案 1 :(得分:2)
您可能需要返回一步并进行更多阅读,此代码相当先进,您的问题表明您还没有阅读过这些内容。我推荐Scott Meyers的Modern Effective C ++。至于你的具体问题:
typename
,因为我们正在处理模板类的成员,这是一个依赖类型。可以把它想象为确保编译器这个东西真的是一个类型,在编译器可以验证它之前(因为模板尚未实例化,只是定义了,所以它不知道T
是什么)。std::forward
的想法是明确指定模板参数以使其正常工作。此表单禁用类型推导,这在此上下文中是可取的(罕见)。请注意,删除引用并将其添加回来与不执行任何操作不同,就好像它不是引用的引用一样,它仍然最终为一个引用。那就是目标;总是采用左值参考。constexpr
。如果函数标记为constexpr
,则可以在常量表达式中使用该函数。并非所有功能都可以标记为constexpr
,但存在限制。标准库函数std::forward
可以是constexpr,但根本不是。此功能只是解决方法。std::forward
,所以最好去谷歌并阅读它,因为这不是一件容易的事情(我提到的那本书谈论它)。基本上这个想法是,一旦你有一个接受一组参数的函数,假设它想把这些参数转发到其他地方。问题是所有的符号名称(在这种情况下,args
)都被认为是左值(即使它们是右值引用......正如我所说,它令人困惑,类型与值类别)。但是,如果用户传入任何临时值,那么我们希望它能够正确地(即作为临时)转发到下一个函数。 std::forward
确保以rvalues方式传入的内容,被转换回rvalue引用,并可由内部函数正确使用。我希望有所帮助。同样,您需要花一些时间阅读以更深入地了解值类别,并使用右值引用来完全消化它。