- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
C++11(和 C++14)引入了针对泛型编程的附加语言结构和改进。这些包括以下功能;
template<class F, class Tuple, std::size_t... I>
decltype(auto) apply_impl(F&& f, Tuple&& t, index_sequence<I...>) {
return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
}
template<class F, class Tuple>
decltype(auto) apply(F&& f, Tuple&& t) {
using Indices = make_index_sequence<std::tuple_size<Tuple>::value>;
return apply_impl(std::forward<F>(f), std::forward<Tuple>(t), Indices());
}
f
在 apply_impl
被转发,即为什么std::forward<F>(f)(std::get...
? f(std::get...
? 最佳答案
简单来说...
TL;DR,您想保留 value category (r 值/l 值性质),因为这会影响 overload resolution ,尤其是 ref-qualified members .
函数定义缩减
为了关注被转发函数的问题,我将示例(并使用 C++11 编译器编译)缩减为;
template<class F, class... Args>
auto apply_impl(F&& func, Args&&... args) -> decltype(std::forward<F>(func)(std::forward<Args>(args)...)) {
return std::forward<F>(func)(std::forward<Args>(args)...);
}
我们创建了第二个表单,我们替换了
std::forward(func)
只需
func
;
template<class F, class... Args>
auto apply_impl_2(F&& func, Args&&... args) -> decltype(func(std::forward<Args>(args)...)) {
return func(std::forward<Args>(args)...);
}
sample 评估
struct Functor1 {
int operator()(int id) const
{
std::cout << "Functor1 ... " << id << std::endl;
return id;
}
};
初始样本
int main()
{
Functor1 func1;
apply_impl_2(func1, 1);
apply_impl_2(Functor1(), 2);
apply_impl(func1, 3);
apply_impl(Functor1(), 4);
}
并且输出如预期,与是否使用 r 值无关
Functor1()
或左值
func
拨打
apply_impl
时和
apply_impl_2
调用重载的调用运算符。它被称为 r 值和 l 值。在 C++03 下,这就是你所得到的,你不能基于对象的“r-value-ness”或“l-value-ness”重载成员方法。
Functor1 ... 1
Functor1 ... 2
Functor1 ... 3
Functor1 ... 4
struct Functor2 {
int operator()(int id) const &
{
std::cout << "Functor2 &... " << id << std::endl;
return id;
}
int operator()(int id) &&
{
std::cout << "Functor2 &&... " << id << std::endl;
return id;
}
};
我们运行另一个样本集;
int main()
{
Functor2 func2;
apply_impl_2(func2, 5);
apply_impl_2(Functor2(), 6);
apply_impl(func2, 7);
apply_impl(Functor2(), 8);
}
输出是;
Functor2 &... 5
Functor2 &... 6
Functor2 &... 7
Functor2 &&... 8
apply_impl_2
的情况下(
id
5 和 6),输出可能与最初预期的不同。在这两种情况下,l 值都符合条件
operator()
被调用(根本不调用 r 值)。从
Functor2()
开始,可能已经预料到了,一个 r 值,用于调用
apply_impl_2
r 值合格
operator()
会被调用。
func
, 作为
apply_impl_2
的命名参数, 是一个 r 值引用,但由于它被命名,它本身就是一个左值。因此 l 值合格
operator()(int) const&
在 l 值
func2
的两种情况下都被调用作为参数和 r 值
Functor2()
被用作论据。
apply_impl
的情况下(
id
7 和 8)
std::forward<F>(func)
维护或保留为
func
提供的参数的 r 值/l 值性质.因此 l 值合格
operator()(int) const&
用 l 值
func2
调用用作参数和 r 值限定
operator()(int)&&
当 r 值
Functor2()
用作参数。这种行为是预料之中的。
std::forward
的使用,通过完美转发,确保我们保留 func
的原始参数的 r 值/l 值性质。 .它保留了他们的 value category .
std::forward
可以而且应该不仅仅用于将参数转发给函数,而且还可以用于必须保留 r-value/l-value 性质的参数的使用。笔记;在某些情况下,不能或不应保留 r 值/l 值,在这些情况下
std::forward
不应使用(参见下面的反面)。
std::forward<T>(t)
. std::forward
解决所有“通用引用”问题?不,它没有,有些情况下它 should not be used ,例如多次转发该值。 std::forward
的工作原理(大约在 20 分钟标记处);
template <typename T>
T&& forward(T&& param) { // T&& here is formulated to disallow type deduction
if (is_lvalue_reference<T>::value) {
return param; // return type T&& collapses to T& in this case
}
else {
return move(param);
}
}
完美转发依赖于一些 C++11 新的基本语言结构,它们构成了我们现在在泛型编程中看到的大部分内容的基础:
std::forward
的使用当前用于公式
std::forward<T>
,了解如何
std::forward
作品有助于理解为什么会这样,还有助于识别非惯用或不正确的右值使用、引用折叠和同类。
&
和右值引用限定符
&&
)类似于 cv 限定符,因为它们(
ref-qualified members)在
overload resolution 期间使用来确定调用哪个方法。他们的行为与您期望的一样;
&
适用于左值和
&&
到右值。
注:与 cv-qualification 不同,
*this
仍然是一个左值表达式。
关于c++ - 为什么要使用完美转发的值(仿函数)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24779910/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!