《C++ Primer Plus》(第6版)第18章编程练习
- 《C++ Primer Plus》(第6版)第18章编程练习
- 1. 函数average_list()
- 2.
- 3. sum_value()
- 4. 使用lambda重新编写程序清单16.15
《C++ Primer Plus》(第6版)第18章编程练习
1. 函数average_list()
下面是一个简短程序的一部分:
int main()
{
using namespace std;
// list of double deduced from list contents
auto q = average_list({15.4, 10.7, 9.0});
cout << q << endl;
// list of int deduced from list contents
cout << average_list({20, 30, 19, 17, 45, 38} ) << endl;
// forced list of double
auto ad = average_list<double>({'A', 70, 65.33});
cout << ad << endl;
return 0;
}
请提供函数average_list(),让该程序变得完整。它应该是一个模板函数,其中的类型参数指定了用作函数参数的initializer_list模板的类型以及函数的返回类型。
程序:
#include <iostream>
#include <initializer_list>
#include <algorithm>
using namespace std;
template <typename T>
T average_list(initializer_list<T> l);
int main()
{
// list of double deduced from list contents
auto q = average_list({15.4, 10.7, 9.0});
cout << q << endl;
// list of int deduced from list contents
cout << average_list({20, 30, 19, 17, 45, 38}) << endl;
// forced list of double
auto ad = average_list<double>({'A', 70, 65.33});
cout << ad << endl;
system("pause");
return 0;
}
template <typename T>
T average_list(initializer_list<T> l)
{
T sum = 0;
if (l.size() == 0)
return 0;
for_each(l.begin(), l.end(), [&sum](T t) { sum += t; });
return sum / l.size();
}
运行结果:
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
{
string qcode;
string zcode;
};
private:
Info *pi;
public:
Cpmv();
Cpmv(string q, 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;
};
int main()
{
Cpmv c1;
Cpmv c2("abc", "123");
Cpmv c3(c2);
c1 = c2;
c1.Display();
Cpmv c4(move(c1));
c4.Display();
Cpmv c5;
c5 = move(c2);
c5.Display();
Cpmv c6("abc", "123");
Cpmv c7("def", "456");
Cpmv c8 = c6 + c7;
c8.Display();
system("pause");
return 0;
}
Cpmv::Cpmv()
{
pi = new Info;
pi->qcode = "";
pi->zcode = "";
cout << "Cpmv() called.\n";
}
Cpmv::Cpmv(string q, string z)
{
pi = new Info;
pi->qcode = q;
pi->zcode = z;
cout << "Cpmv(string q, string z) called.\n";
}
Cpmv::Cpmv(const Cpmv &cp)
{
pi = new Info;
pi->qcode = cp.pi->qcode;
pi->zcode = cp.pi->zcode;
cout << "Cpmv(const Cpmv &cp) called.\n";
}
Cpmv::Cpmv(Cpmv &&mv)
{
pi = mv.pi;
mv.pi = nullptr;
cout << "Cpmv(Cpmv &&mv) called.\n";
}
Cpmv::~Cpmv()
{
delete pi;
cout << "~Cpmv() called.\n";
}
Cpmv &Cpmv::operator=(const Cpmv &cp)
{
cout << "Cpmv &operator=(const Cpmv &cp) called.\n";
if (this == &cp)
return *this;
delete pi;
pi = new Info;
pi->qcode = cp.pi->qcode;
pi->zcode = cp.pi->zcode;
return *this;
}
Cpmv &Cpmv::operator=(Cpmv &&mv)
{
cout << "Cpmv &operator=(Cpmv &&mv) called.\n";
if (this == &mv)
return *this;
delete pi;
pi = mv.pi;
mv.pi = nullptr;
return *this;
}
Cpmv Cpmv::operator+(const Cpmv &obj) const
{
cout << "Cpmv operator+(const Cpmv &obj) const called.\n";
Cpmv cv;
cv.pi->qcode = pi->qcode + obj.pi->qcode;
cv.pi->zcode = pi->zcode + obj.pi->zcode;
return cv;
}
void Cpmv::Display() const
{
cout << "The qcode is " << pi->qcode << endl;
cout << "The zcode is " << pi->zcode << endl;
}
运行结果:
3. sum_value()
编写并测试可变参数模板函数sum_value( ),它接受任意长度的参数列表(其中包含数值,但可以是任何类型),并以long double的方式返回这些数值的和。
程序:
在这里插入代码片
运行结果:
4. 使用lambda重新编写程序清单16.15
使用lambda重新编写程序清单16.15。具体地说,使用一个有名称的lambda替换函数outint( ),并将函数符替换为两个匿名lambda表达式。
程序:
在这里插入代码片
运行结果: