我编写了以下设计代码,以便探索一些想法并了解有关C ++的更多信息。我所拥有的是Accountant class
,其中包含有关会计师的信息以及Accountants class
,其中包含会计师的矢量以及一些方法。
该代码还使用lambda来查找并打印具有一定范围内薪水的Accountants
。
我要做的是创建一个方法,根据任意传入的lambda返回一个Accountants
对象。
代码如下:
#include <functional>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
// just contains information about an Accountant
class Accountant
{
private:
std::string m_name;
double m_salary; // yes dealing with currency it's not good to use float types. I KNOW
public:
Accountant() {}
Accountant( std::string _name, double _salary ) : m_name( _name ), m_salary( _salary ) {}
double salary() const { return( m_salary ); }
std::string name() const { return( m_name); }
friend std::ostream& operator << (std::ostream &out, const Accountant &accountant);
};
std::ostream& operator << (std::ostream &out, const Accountant &accountant)
{
out << accountant.name() << " " << accountant.salary();
return(out);
}
// contains a vector of Accountant and performs operations on them
class Accountants
{
private:
std::vector<Accountant> m_list;
public:
Accountants( std::vector<Accountant> list ) : m_list( list ) {}
friend std::ostream& operator << (std::ostream &out, const Accountants &m_list);
// how to implement something like this?
//
Accountants subset( .... some lambda ...... );
};
Accountants Accountants::subset( .... some lambda .....)
{
// perform std::find_if() with lambda has parameter and return an Accountants object.
// what would be even better is have a way to more flexibly and
// generically pass in lambda so almost any search criteria can be used to
// return Accountants subset.
}
std::ostream& operator << (std::ostream &out, const Accountants &list)
{
std::vector<Accountant>::const_iterator iter = list.m_list.begin();
while (iter != list.m_list.end())
{
out << *iter << std::endl;
++iter;
}
return(out);
}
int main(int argc, char *argv[])
{
std::vector<Accountant> emps{{"Josh",2100.0}, {"Kate", 2900.0}, {"Rose",1700.0}};
Accountants list( emps );
const auto min_wage = 0.0;
const auto upper_limit = 2900.0;
auto lambda = ([=]( Accountant &a ){ return (a.salary() >= min_wage && a.salary() < upper_limit); });
std::cout << "List of Accountants" << std::endl << list << std::endl;
std::cout << "===============================================" << std::endl;
std::vector<Accountant>::iterator items = std::find_if(emps.begin(), emps.end(), lambda );
while( items != emps.end() )
{
std::cout << (*items).name() << " " << (*items).salary() << std::endl;
items = std::find_if(++items, emps.end(), lambda );
}
// how to implement something like this?
Accountants inRangeAccountants = list.subset( lambda );
return( 0 );
}
我可以使用哪些方法,如果可能的话,编码样本,以创建一个方法,如:
Accountants inRangeAccountants = list.subset( lambda );
这样“lambda”可以是任意的吗?我们的想法是能够使用subset()
方法返回一个Accountants
对象,该对象包含与lambda中指定的搜索条件相同的项目。类似于main()中的代码,它返回特定薪资范围内的会计。
我在想模板和std :: function需要使用吗?
任何有关代码示例的帮助都将不胜感激。
答案 0 :(得分:4)
可以这么简单:
template <typename Lambda>
Accountants subset(Lambda func)
{
/* your code that calls func() */
}
如果您想要的只是lambda参数值,则不需要使用std::function
。如果您传递subset
无法作为函数调用的参数,代码将无法编译。
答案 1 :(得分:2)
最简单的方法是使用std::function<bool( const Account &)>
作为参数。在这种情况下,你将要通过不同的lambdas。
例如
Accountants Accountants::subset( std::function<bool( const Account &)> f ) const;
您可以通过以下方式调用该方法
Accounts a1( /* some arguments */ );
Accounts a2 = a1.subset( []( const Account &a ) { return a.salary() < 5000; } );
或
Accounts a2 = a1.subset( []( const Account &a ) { return a.name().front() == 'A'; } );
使用std :: function,您可以使用函数,lambda,函数对象。所以不需要使用模板。
答案 2 :(得分:2)
您的subset
函数应该采用任何类型的可调用函数,因此请将其作为成员函数模板。然后使用copy_if
将与谓词匹配的Accountant
复制到结果中。
template<typename Callable>
Accountants subset(Callable&& c)
{
std::vector<Accountant> result;
std::copy_if(m_list.begin(), m_list.end(),
std::back_inserter(result), std::forward<Callable>(c));
return result;
}