有人能告诉我为什么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
对象本身的内存地址,而不是它持有的1的ptr_
的值。该地址永远不会为空。
1:除非Value
覆盖operator&
返回ptr_
,否则不应该这样做
您需要删除&
,以便比较实际的Value
对象。但是,只有当Value
实现了operator==
以T*
(其中T
是ptr_
的类型(或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_
(其中T
是ptr_
的类型(,然后可以这样做:
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 &
的指针(带有&
(。