《C++ Primer Plus》(第6版)第18章编程练习
《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
下面是类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有操作数的相应成员拼接而成。请提供为移动构造函数和移动赋值运算符实现移动语义的代码。编写一个使用所有这些方法的程序。为方便测试,让各个方法都显示特定的内容,以便知道它们被调用。
程序:
cpmv.h:
#ifndef CPMV_H
#define CPMV_H
#include <string>
using std::string;
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;
};
#endif
cpmv.cpp:
#include <iostream>
#include "cpmv.h"
int main()
{
using std::move;
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;
}
运行结果:
C:\Users\81228\Documents\Program\VScode C++ Program\chapter18\18.2>g++ cpmv.cpp use_cpmv.cpp -o use_cpmv
C:\Users\81228\Documents\Program\VScode C++ Program\chapter18\18.2>use_cpmv
Cpmv() called.
Cpmv(string q, string z) called.
Cpmv(const Cpmv &cp) called.
Cpmv &operator=(const Cpmv &cp) called.
The qcode is abc
The zcode is 123
Cpmv(Cpmv &&mv) called.
The qcode is abc
The zcode is 123
Cpmv() called.
Cpmv &operator=(Cpmv &&mv) called.
The qcode is abc
The zcode is 123
Cpmv(string q, string z) called.
Cpmv(string q, string z) called.
Cpmv operator+(const Cpmv &obj) const called.
Cpmv() called.
The qcode is abcdef
The zcode is 123456
请按任意键继续. . .
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
~Cpmv() called.
C:\Users\81228\Documents\Program\VScode C++ Program\chapter18\18.2>
3. sum_value()
编写并测试可变参数模板函数sum_value( ),它接受任意长度的参数列表(其中包含数值,但可以是任何类型),并以long double的方式返回这些数值的和。
程序:
#include <iostream>
using namespace std;
template <typename T>
long double sum_value(const T &value);
template <typename T, typename... Args>
long double sum_value(const T &value, const Args &...args);
int main()
{
cout << sum_value(1, 2, 3, 4, 5) << endl;
system("pause");
return 0;
}
template <typename T>
long double sum_value(const T &value)
{
return value;
}
template <typename T, typename... Args>
long double sum_value(const T &value, const Args &...args)
{
return value + sum_value(args...);
}
运行结果:
4. 使用lambda重新编写程序清单16.15
使用lambda重新编写程序清单16.15。具体地说,使用一个有名称的lambda替换函数outint( ),并将函数符替换为两个匿名lambda表达式。
程序:
#include <iostream>
#include <list>
#include <iterator>
#include <algorithm>
using namespace std;
auto outint = [](int n) { cout << n << " "; };
int main()
{
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);
cout << endl;
for_each(etcetera.begin(), etcetera.end(), outint);
cout << endl;
yadayada.remove_if([](int n) { return n > 100; });
etcetera.remove_if([](int n) { return n > 200; });
cout << "Trimmed lists:\n";
for_each(yadayada.begin(), yadayada.end(), outint);
cout << endl;
for_each(etcetera.begin(), etcetera.end(), outint);
cout << endl;
system("pause");
return 0;
}
运行结果: