C++ 成员变量与STL算法 #包括 #包括 #包括 使用名称空间std; 结构Foo { int i; 双d; Foo(整数i,双d): i(i),, d(d) {} int getI()常量{return i;} }; int main() { 向量v; v、 推回(Foo(1,2.0)); v、 推回(Foo(5,3.0)); 向量是; 转换(v.begin()、v.end()、back_inserter(is)、mem_fun_ref(&Foo::getI)); 返回0; }
有没有一种更干净的方法来访问成员变量,然后使用上面提到的成员函数?我知道如何使用tr1::bind来实现这一点,但我需要在没有boost的情况下使用与C++03兼容的代码 这样做需要访问器函数是绝对不干净的。但这就是当前的C++。 您可以尝试使用C++ 成员变量与STL算法 #包括 #包括 #包括 使用名称空间std; 结构Foo { int i; 双d; Foo(整数i,双d): i(i),, d(d) {} int getI()常量{return i;} }; int main() { 向量v; v、 推回(Foo(1,2.0)); v、 推回(Foo(5,3.0)); 向量是; 转换(v.begin()、v.end()、back_inserter(is)、mem_fun_ref(&Foo::getI)); 返回0; },c++,stl,C++,Stl,有没有一种更干净的方法来访问成员变量,然后使用上面提到的成员函数?我知道如何使用tr1::bind来实现这一点,但我需要在没有boost的情况下使用与C++03兼容的代码 这样做需要访问器函数是绝对不干净的。但这就是当前的C++。 您可以尝试使用boost::bind,这非常容易实现,或者使用for(vector::const_iterator it=v.begin();…)循环显式迭代向量。我发现,当创建函子变得太麻烦时,后者通常会导致代码更清晰 或者,避开boost,创建自己的成员访问器sh
boost::bind
,这非常容易实现,或者使用for(vector::const_iterator it=v.begin();…)
循环显式迭代向量。我发现,当创建函子变得太麻烦时,后者通常会导致代码更清晰
或者,避开boost,创建自己的成员访问器shim函数
#include <vector>
#include <functional>
#include <algorithm>
using namespace std;
struct Foo
{
int i;
double d;
Foo(int i, double d) :
i(i),
d(d)
{}
int getI() const { return i; }
};
int main()
{
vector<Foo> v;
v.push_back(Foo(1, 2.0));
v.push_back(Foo(5, 3.0));
vector<int> is;
transform(v.begin(), v.end(), back_inserter(is), mem_fun_ref(&Foo::getI));
return 0;
}
templatestruct访问器{
类型定义m(T::*成员PTR);
行政协调委员会成员;
访问器(memberptr acc):acc(acc){}
//存取器_t(m(t::*acc)):acc_(acc){}
//m(T::*附件);
常量m&运算符()(常量T&T)常量{return(T.*acc)}
m&operator()(T&T)const{return(T.*acc)}
};
模板访问器\u T访问器(mt::*acc){
返回存取器(acc);
}
...
转换(v.begin()、v.end()、back_插入器(is)、访问器(&C::i));
对我来说,最清楚的方法是:
#包括
...
转换(v.begin(),v.end(),back_插入器(is),bind(&Foo::i,_1));
当然,您可以创建自己的成员访问函数,但我相信这会降低代码的可读性。bind是一个广为人知的库,所以使用它可以使您的代码非常可读,并且无需阅读助手函数(有时可能会包含bug)
我更喜欢的第二种方法是使用for循环(在这种特殊情况下):
for(vector::const_迭代器it=v.begin(),it!=v.end();++it)
is.push_back(it->i);
也许使用这样简单的循环并不流行,但它们非常清晰。像std::pair一样,您可以编写访问或对象
for ( vector<Foo>::const_iterator it = v.begin(), it != v.end(); ++it )
is.push_back( it->i );
#包括
#包括
结构Foo
{
int i;
双d;
};
结构GetI{int operator()(Foo const&o)const{return o.i;};
struct GetD{double operator()(Foo const&o)const{return o.d;};
int main()
{
std::向量v;
std::向量t;
std::transform(v.begin()、v.end()、std::back_inserter(t)、GetI());
}
注意:您应该查看std::pair以及它的访问器:std::select1st和std::select2nd
如果操作符()返回一个引用不是更好吗<代码>
等等,m
无论如何都是一个指针,不是吗<代码>
天哪,我从来没有真正爱上过成员指针,尽管我自己偶尔会摆弄一下(即使是模板化的指针),但我确实很难理解这一点<代码>
它还可以返回常量引用(因为常量引用将T传递给函数运算符)。对于int,这并不重要。您对accessor()
的参数声明无法推断t
和m
——请在此处指定完整类型(即mt::*acc
),这使这些模板参数可推断,或者在调用站点指定所有模板参数(即accessor(&C::i)
)。@sbi:试图通过引入typedef使其更具可读性。@j_random_hacker:我这样做有点太热情了……我把它往后退了。@UncleBens和@sbi:的确,操作符()
应该返回对成员本身的引用;如果提供了const参数,则返回const,否则返回non-const。对此进行了更正。我同意,但不幸的是,我不能使用boost或tr1 bind。我的印象是boost/tr1 mem\u fn也可以这样做(没有占位符),但在您的情况下,xtofl似乎有答案。
#include <boost/bind.hpp>
...
transform(v.begin(), v.end(), back_inserter(is), bind( &Foo::i, _1 ) );
for ( vector<Foo>::const_iterator it = v.begin(), it != v.end(); ++it )
is.push_back( it->i );
#include <vector>
#include <algorithm>
struct Foo
{
int i;
double d;
};
struct GetI { int operator()(Foo const& o) const { return o.i;}};
struct GetD { double operator()(Foo const& o) const { return o.d;}};
int main()
{
std::vector<Foo> v;
std::vector<int> t;
std::transform(v.begin(), v.end(), std::back_inserter(t),GetI() );
}