Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;std::成对的变换向量->;先到新向量_C++_Vector_Transform_Functor_Std Pair - Fatal编程技术网

C++ C++;std::成对的变换向量->;先到新向量

C++ C++;std::成对的变换向量->;先到新向量,c++,vector,transform,functor,std-pair,C++,Vector,Transform,Functor,Std Pair,对不起,有一点初学者的问题。有向量和向量对 typedef std::vector <int> TItems; typedef std::vector < std::pair <int, int> > TPairs; 如何设计函子 class comp { private: TPairs *pairs; public: comp ( TPairs *pairs_ ) : pairs ( pairs_) { } unsigned

对不起,有一点初学者的问题。有向量和向量对

typedef std::vector <int> TItems;
typedef std::vector < std::pair <int, int> > TPairs;
如何设计函子

class comp
{
private:
     TPairs *pairs;

public:
    comp ( TPairs  *pairs_ ) : pairs ( pairs_) { }

    unsigned int operator () ( const unsigned int index ) const
    {
        return  (*pairs)[index].second != pairs->end();  //Bad idea
    }
};
也许有一些没有lambda表达式和循环的更用户友好的方法。谢谢你的帮助。

这个怎么样

items.reserve(pairs.size());
for (size_t it = 0; it < pairs.size(); ++it) {
    items.push_back(pairs[it].first);
}
items.reserve(pairs.size());
for(size_t it=0;it

易于理解和调试。

首先,应使用a作为第三个参数,以便将转换后的值推送到向量的后面

其次,需要某种函子,它接受一对整数并返回第一个整数。这应该做到:

int firstElement( const std::pair<int, int> &p ) {
    return p.first;
}

在此代码之后,
项包含1和5。

使用
std::bind如何

std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               std::bind(&TPairs::value_type::first, std::placeholders::_1));

(对于非C++11代码,用
boost::bind
替换
std::bind

参见frerich或kotlinski关于C++03的回答

使用lambda的C++11解决方案:

std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               [](const std::pair<int, int>& p) { return p.first; });
std::transform(pairs.begin(), pairs.end(), 标准:背面插入器(项目), [](const std::pair&p){return p.first;});
我真的希望您使用
std::get
作为functor,因为它已经作为库函数提供了

如果我们能写这句话岂不是太好了

std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
问题是,
std::get
取1<代码>配对&
,2<代码>常量对&
,和3
pair&&
作为参数,因此它可以作为输入用于任何类型的pair。不幸的是,重载妨碍了
std::transform
的模板类型推断,因此我们的原始行

std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
屈服

 error: no matching function for call to ‘transform(std::vector<std::pair<int, int> >::iterator, std::vector<std::pair<int, int> >::iterator, std::back_insert_iterator<std::vector<int> >, <unresolved overloaded function type>)’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
                                                                                    ^
...

/usr/include/c++/4.8/bits/stl_algo.h:4915:5: note:   template argument deduction/substitution failed:
 note:   couldn't deduce template parameter ‘_UnaryOperation’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
错误:调用“transform(std::vector::iterator,std::vector::iterator,std::back\u insert\u iterator,)时没有匹配的函数”
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
^
...
/usr/include/c++/4.8/bits/stl_algo.h:4915:5:注意:模板参数推导/替换失败:
注意:无法推断模板参数“\u UnaryOperation”
std::transform(pairs.begin()、pairs.end()、std::back\u插入器(items)、std::get);
在为
std::transform
推导模板时,它不知道您需要哪个
std::get
重载,因此您必须手动指定它。将函数指针投射到正确的类型会告诉编译器,“嘿,请使用重载,
get
获取一个
const&
并返回一个
const&
!”

但至少我们使用的是标准库组件(yay)

就行数而言,它并不比其他选项差:
C++11的另一种可能性是,这与使用
std::bind的解决方案类似:

std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               std::mem_fn(&std::pair<int,int>::first)               
);
std::transform(pairs.begin(), pairs.end(), 标准:背面插入器(项目), std::mem_fn(&std::pair::first) );
@kotlinski:谢谢,但这是一个常见的解决方案。我想找到一个没有任何循环的一步解决方案,如果可能的话,你需要一些用户友好的,那么这将是误导性的答复与一些C++的暴行:+ 1:在这种情况下最简单。如果循环简化,为什么要避免循环?@stefaanv:因为OP明确要求回答
没有lambda表达式和循环。
@Frerich:我的“为什么”实际上指的是这个限制,但我承认这并不清楚。哎呀,我没有注意到“没有lambda”的要求,但是为什么当它是直截了当的,并且是语言的一部分时,我相信它不是C++语言的一部分,大多数人都可以使用(无论是由于编译器的限制还是因为工作场所的某些要求)。有没有使用自定义函数的巧妙方法?有人能想到什么改进吗?能够像这样干净地使用
std::get
,那就太好了。。。实际上,我可能应该使用
reinterperet_cast(std::get)
,但这似乎更糟……我认为可以用包装在lambda中的get函数替换“硬”cast,可以为其指定参数
std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
 error: no matching function for call to ‘transform(std::vector<std::pair<int, int> >::iterator, std::vector<std::pair<int, int> >::iterator, std::back_insert_iterator<std::vector<int> >, <unresolved overloaded function type>)’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
                                                                                    ^
...

/usr/include/c++/4.8/bits/stl_algo.h:4915:5: note:   template argument deduction/substitution failed:
 note:   couldn't deduce template parameter ‘_UnaryOperation’
   std::transform(pairs.begin(), pairs.end(), std::back_inserter(items), std::get<0>);
std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               std::mem_fn(&std::pair<int,int>::first)               
);