C++ Primer Plus章节编程练习第十八章
1
题目
下面是一个简短程序的一部分:
int main(){
using namespace std;
auto q=average_list({15.4,10.7,9.0});
cout<<q<<endl;
cout<<average_list({20,30,19,17,45,38})<<endl;
auto ad=average_list<double>({'A',70,65.33});
cout<<ad<<endl;
return 0;
}
请提供函数average_list(),让该程序变得完整。它应该是一个模板函数,其中的类型参数指定了用作函数参数的initilize_list 模板的类型以及函数的返回类型。
题解
#include<iostream>
#include<vector>
#include<initializer_list>
template<typename T>
T average_list(std::initializer_list<T> values){
T average=0;
for(auto item:values) average+=item;
return values.size()==0?0:average/values.size();
}
int main(){
using namespace std;
auto q=average_list({15.4,10.7,9.0});
cout<<q<<endl;
cout<<average_list({20,30,19,17,45,38})<<endl;
auto ad=average_list<double>({'A',70,65.33});
cout<<ad<<endl;
return 0;
}
2
题目
下面是类Cpmv的声明:
class Cpmv{
public:
struct Info{
std::string qcode;
std::string zcode;
};
private:
Info *pi;
public:
Cpmv();
Cpmv(std::string q,std::string z);
Cpmv(const Cpmv&cp);
Cpmv(Cpmv &&mv);
~Cpmv();
Cpmv& operator=(const Cpmv&cp);
Cpmv& operator=(Cpmv&&mv);
Cpmv operator+(const Cpmv& obj)const;
void Display()const;
};
函数operator+()应创建一个对象,其成员qcode和zcode有操作数的相应成员拼接而成。请提供为移动构造函数和移动赋值运算符实现移动语义的代码。编写一个使用所有这些方法的程序。为方便测试,让各个方法都显示特定的内容,以便知道它们被调用。
题解
#include<iostream>
#include<string>
using namespace std;
class Cpmv{
public:
struct Info{
std::string qcode;
std::string zcode;
};
private:
Info *pi;
public:
Cpmv();
Cpmv(std::string q,std::string z);
Cpmv(const Cpmv&cp);
Cpmv(Cpmv &&mv);
~Cpmv();
Cpmv& operator=(const Cpmv&cp);
Cpmv& operator=(Cpmv&&mv);
Cpmv operator+(const Cpmv& obj)const;
void Display()const;
};
Cpmv::Cpmv(){
pi=new Info;
cout<<"Default Constructor called!"<<endl;
}
Cpmv::Cpmv(std::string q, std::string z){
pi=new Info;
pi->qcode=q;
pi->zcode=z;
cout<<"String Constructor called!"<<endl;
}
Cpmv::Cpmv(const Cpmv& cp){
pi=new Info;
pi->qcode=cp.pi->qcode;
pi->zcode=cp.pi->zcode;
cout<<"Copy Constructor called!"<<endl;
}
Cpmv::Cpmv(Cpmv&& cp){
pi=cp.pi;
cp.pi=nullptr;
cout<<"Move Constructor called!"<<endl;
}
Cpmv::~Cpmv(){
delete pi;
cout<<"Destrutor called!"<<endl;
}
Cpmv& Cpmv::operator=(const Cpmv&cp){
if(this==&cp) return *this;
pi=new Info;
pi->qcode=cp.pi->qcode;
pi->zcode=cp.pi->zcode;
cout<<"Assignment called!"<<endl;
return *this;
}
Cpmv& Cpmv::operator=(Cpmv&&mv){
pi=mv.pi;
mv.pi=nullptr;
cout<<"Move Assignment called!"<<endl;
return *this;
}
Cpmv Cpmv::operator+(const Cpmv& obj)const{
string qcode=pi->qcode+obj.pi->qcode;
string zcode=pi->zcode+obj.pi->zcode;
cout<<"Operator+() called!"<<endl;
return Cpmv(qcode,zcode);
}
void Cpmv::Display()const{
cout<<"Display called!"<<endl;
cout<<"Qcode: "<<pi->qcode<<endl;
cout<<"Zcode: "<<pi->zcode<<endl;
}
int main(){
using namespace std;
Cpmv one; //默认构造函数
Cpmv two("qcode","zcode"); //传参构造函数
Cpmv three(two); //复制构造函数
Cpmv four(move(three+two)); //移动构造函数 ,其中调用了重载的+运算符,传参构造函数和析构函数
Cpmv five; //默认构造函数
five=four; //赋值操作符
Cpmv six; //默认构造函数
six=move(five); //移动赋值操作符
six.Display();
return 0;
}
3
题目
编写并测试可变参数模板函数sum_value(),它接受任意长度的参数列表(其中包含数值,但可以是任何类型),并以long double的方式返回这些数值的和。
题解
#include<iostream>
// template<class T>
// long double sum_value(){return 0;}
template<class T>
long double sum_value(T value){return value;}
template<class T,class... Args>
long double sum_value(T value, Args... args){
return value+sum_value(args...);
}
int main(){
using namespace std;
cout<<sum_value(1,2,3,4,5,6,7,8,9,10)<<endl;
cout<<sum_value(100.00,3,20.99,4.6,3.6)<<endl;
return 0;
}
4
题目
使用lambda重新编写程序清单16.15。具体地说,使用一个有名称的lambda替换函数outint(),并将函数符替换为两个匿名lambda表达式。
题解
#include<iostream>
#include<list>
#include<iterator>
#include<algorithm>
template<class T>
class TooBig{
private:
T cutoff;
public:
TooBig(const T &t):cutoff(t){}
bool operator()(const T &v){return v>cutoff;}
};
auto outint_lambda=[](int n){std::cout<<n<<std::endl;};
int main(){
using namespace std;
TooBig<int> f100(100);
int vals[10]={50,100,90,180,60,210,415,88,188,201};
list<int> yadayada(vals,vals+10);
list<int> etcetera(vals,vals+10);
cout<<"Original lists:\n";
for_each(yadayada.begin(),yadayada.end(),outint_lambda);
cout<<endl;
yadayada.remove_if(f100); //删除大于100的数字
etcetera.remove_if(TooBig<int>(200)); //删除大于两百的数字
cout<<"Trimmed lists:\n";
for_each(yadayada.begin(),yadayada.end(),outint_lambda);
cout<<endl;
for_each(etcetera.begin(),etcetera.end(),outint_lambda);
cout<<endl;
return 0;
}
//由16.15改编
Comments | NOTHING