c++for_each()lamda函数不正确



有人能告诉我为什么for_each()在下面的代码中不起作用吗。

我需要它来检查元组中的第三个元素是否不是nullptr,如果不是,则将第一个和第三个添加到list

然而,它似乎在向list添加所有元素。

std::vector<std::tuple<std::string, std::type_index, Value>> arguments;

std::vector<std::pair<std::string, mv::Value>> class::defaultValues() const
{
std::vector<std::pair<std::string, Value>> list;
list.reserve((arguments.size()));
std::for_each(arguments.begin(), arguments.end(),[&list](std::tuple<std::string, std::type_index, Value> arg)
{
if (&std::get<2>(arg) != nullptr)
list.push_back(make_pair(std::get<0>(arg),std::get<2>(arg)));
}
);
return list;
}

更新:

Value是一个类。

默认构造函数的调用,它将ptr_填充为nullptr

Value() : ptr_(nullptr)
{
}

&std::get<2>(arg)返回Value对象本身的内存地址,而不是它持有的1ptr_。该地址永远不会为空。

1:除非Value覆盖operator&返回ptr_,否则不应该这样做

您需要删除&,以便比较实际的Value对象。但是,只有当Value实现了operator==T*(其中Tptr_的类型(或nullptr_t作为输入并将其与ptr_进行比较时,这在您的示例中才会起作用。否则,您的lambda将不得不直接访问并比较ptr_

您还应该通过引用而不是通过值传递lambda的arg参数,这样您就可以对存储在arguments中的原始tuple执行操作,而不是对其副本执行操作。

试试这个:

std::for_each(arguments.begin(), arguments.end(),
[&list](std::tuple<std::string, std::type_index, Value> &arg)
{
if (std::get<2>(arg) != nullptr) // or std::get<2>(arg).ptr_, depending on how Value is implemented
list.push_back(std::make_pair(std::get<0>(arg), std::get<2>(arg)));
}

在这种情况下,我建议让Value实现operator!(如果它还没有(,以返回它的ptr_是否是nullptr,那么你可以这样做:

std::for_each(arguments.begin(), arguments.end(),
[&list](std::tuple<std::string, std::type_index, Value> &arg)
{
if (!!std::get<2>(arg))
list.push_back(std::make_pair(std::get<0>(arg), std::get<2>(arg)));
}

或者,实现operator bool返回ptr_是否不是nullptr,或者实现operator T*返回ptr_(其中Tptr_的类型(,然后可以这样做:

std::for_each(arguments.begin(), arguments.end(),
[&list](std::tuple<std::string, std::type_index, Value> &arg)
{
if (std::get<2>(arg))
list.push_back(std::make_pair(std::get<0>(arg), std::get<2>(arg)));
}

因为&std::get<2>(arg)永远不可能是nullptr。您实际上得到了一个指向从std::get<2>(arg)返回的某个Value &的指针(带有&(。

最新更新