1.下面是一个简短程序的一部分:
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(),让该程序变得完整。它应该是一个模板函数,其中的类型参数指定了用作函数参数的initilize_list模板的类型以及函数的返回类型。
实现:
#include <iostream>
#include <initializer_list>
using std::cout;
using std::endl;
using std::initializer_list;
template <typename T>
T average_list(initializer_list<T> i)
{
T sum = 0;
int count = 0;
for (auto p = i.begin(); p <= i.end(); p++)
{
count++;
sum += *p;
}
return sum/count;
}
int main(void)
{
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有操作数的相应成员拼接而成。请提供为移动构造函数和移动赋值运算符实现移动语义的代码。编写一个使用所有这些方法的程序。为方便测试,让各个方法都显示特定的内容,以便知道它们被调用。
实现:
class Cpmv
{
public:
struct Info
{
std::string qcode;
std::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(void)
{
Cpmv cp1("c","c++");
Cpmv cp2("computer", "language");
Cpmv cp3(cp2);
cp2 = cp1;
Cpmv cp4(cp1 + cp2);
return 0;
}
Cpmv::Cpmv()
{
pi = nullptr;
cout << "默认构造函数" << endl;
}
Cpmv::Cpmv(string q, string z)
{
pi = new Info;
pi->qcode = q;
pi->zcode = z;
cout << "有参构造函数" << endl;
}
Cpmv::Cpmv(const Cpmv& cp)
{
pi = new Info;
pi->qcode = cp.pi->qcode;
pi->zcode = cp.pi->zcode;
cout << "复制构造函数" << endl;
}
Cpmv::Cpmv(Cpmv&& mv)
{
pi = mv.pi;
mv.pi = nullptr;
cout << "移动构造函数" << endl;
}
Cpmv::~Cpmv()
{
delete pi;
cout << "析构函数" << endl;
}
Cpmv& Cpmv::operator=(const Cpmv& cp)
{
if (this == &cp)
{
return *this;
}
delete pi;
pi = new Info;
pi->qcode = cp.pi->qcode;
pi->zcode = cp.pi->zcode;
cout << "赋值运算符重载函数" << endl;
}
Cpmv& Cpmv::operator=(Cpmv&& mv)
{
if (this == &mv)
{
return *this;
}
delete pi;
pi = mv.pi;
mv.pi = nullptr;
cout << "移动赋值运算符重载函数" << endl;
}
Cpmv Cpmv::operator+(const Cpmv& obj) const
{
return Cpmv(pi->qcode + obj.pi->qcode, pi->zcode + obj.pi->zcode);
cout << "operator+" << endl;
}
void Cpmv::Display() const
{
if (pi == nullptr)
{
cout << "pi is null" << endl;
}
cout << "Adress:" << pi << endl;
cout << "qcode:" << pi->qcode << ", zcode:" << pi->zcode << endl;
cout << "Display()" << endl;
}
3.编写并测试可变参数模板函数sum_value(),它接受任意长度的参数列表(其中包含数值,但可以是任何类型),并以long double的方式返回这些数值的和。
实现:
#include <iostream>
using std::cout;
using std::endl;
long double sum_value() { return 0; }
template <typename T, typename...Args>
long double sum_value(T value, Args...args)
{
long double sum = (long double)value + sum_value(args...);
return sum;
}
int main(void)
{
cout << sum_value(1,2,3,4,5) << endl;
cout << sum_value('a','b',2.2,3.3,5,6,7) << endl;
return 0;
}
4.使用lambba重新编写程序清单16.5。具体地说,使用一个有名称的lambda替换函数outint(),并将函数符替换为两个匿名lambda表达式。
实现:
#include <iostream>
#include <list>
#include <algorithm>
#include <iterator>
using std::cout;
using std::endl;
using std::list;
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 = [](int n) {cout << n << " "; };
int main(void)
{
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 << "Origianl lists: " << endl;
for_each(yadayada.begin(), yadayada.end(), OutInt);
cout << endl;
for_each(etcetera.begin(), etcetera.end(), OutInt);
cout << endl;
cout << "Trimmed lists: " << endl;
yadayada.remove_if([](int n) {return n > 100; });
for_each(yadayada.begin(), yadayada.end(), OutInt);
cout << endl;
etcetera.remove_if([](int n) { return n > 200; });
for_each(etcetera.begin(), etcetera.end(), OutInt);
cout << endl;
return 0;
}