C++ Primer Plus chapter 18

exercies 1

考察 std::initializer_list <>

这份template函数参照简单的例子书写。这种方式会简单很多。

注意到我后面两次调用函数  average_list, 它的 std::initializer_list <>并不相同

#include
#include
#include

double sum(std::initializer_list i)
{
    double tot = 0;
    std::for_each(i.begin(), i.end(), [&tot](double db)
        {
            tot += db;
        }
    );
    return tot;
}

template
T average_list(const std::initializer_list list)
{
    T temp = 0;
    std::for_each(list.begin(), list.end(), [&list,&temp](T value)
        {
            temp += value;
        }
    );
    return temp;
}

int main()
{
    /*double result = sum({2.5,4.2,1.5});
    std::cout << result << "\n";*/
    auto q = average_list({ 2.5,4.2,1.5 });
    std::cout << q << "\n";
    std::cout << average_list({20, 30, 19, 17, 45, 38}) << "\n";
    auto p = average_list({'A', 70, 65.33});    // u pass in a type explicitly
    std::cout << p;
    return 0;
}

exercies 2

在简单的类成员函数的基础上添加了 move semantic,移动构造 和 移动赋值。

driver的驱动函数可以自己实现,没有困难。

#include

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&);
    Cpmv(Cpmv&& rhs);
    ~Cpmv();
    Cpmv& operator=(const Cpmv& cp);
    Cpmv& operator=(Cpmv&&);
    Cpmv operator+(const Cpmv& obj) const;
    void Display() const;
};

Cpmv::Cpmv():
    pi(nullptr)
{   }

Cpmv::Cpmv(std::string q, std::string z)
{
    pi->qcode = q;
    pi->zcode = z;
}

Cpmv::Cpmv(const Cpmv& rhs)
{
    pi = new Info;
    pi->qcode = rhs.pi->qcode;
    pi->zcode = rhs.pi->zcode;
}

Cpmv::Cpmv(Cpmv&& rhs)
{
    pi = rhs.pi;
    rhs.pi = nullptr;
}

Cpmv::~Cpmv()
{
    delete pi;
}

Cpmv& Cpmv::operator=(const Cpmv& cp)
{
    Info* ptmp = pi;
    pi = new Info;
    pi->qcode = cp.pi->qcode;
    pi->zcode = cp.pi->zcode;
    delete ptmp;
}

Cpmv& Cpmv::operator=(Cpmv&& rhs)
{
    delete pi;
    pi = rhs.pi;
    rhs.pi = nullptr;
}

Cpmv Cpmv::operator+(const Cpmv& rhs) const
{
    Cpmv tmp;
    tmp.pi->qcode = pi->qcode + rhs.pi->qcode;
    tmp.pi->zcode = pi->zcode + rhs.pi->zcode;
    return tmp;
}

void Cpmv::Display() const
{
    std::cout << pi->qcode << ", " << pi->zcode;
    return;
}

exercise 3

variadic template 简单的 packing,unpacking,recursion应用

#include
#include

long double sum = 0;
void show_list() {}

template
void show_list(const T value)
{
	sum += value;
	//std::cout << value << '\n';
}

template
void show_list(const T value, const Args... args)
{
	//std::cout << value << ", ";
	sum += value;
	show_list(args...);
}

int main()
{
	int n = 143;
	double x = 2.2345;
	int xyz = 23452;
	std::string mr = "Mr Q, go ahead\n";
	show_list(x,n,xyz);
	//show_list(n, x, mr);
	std::cout << sum;
	return 0;
}

后续更新改进点,不使用全局变量,如何记载数据

需要确认,从设计角度,template function能否有跟类型无关的参数,这是否是正确的、好的设计思路

exercise 4

找不到题目的位置, 把书上18.5抄了一份,作为lambda表达式的例子。

单为了使用 lambda 表达式,不需要这么多的头文件。

#include 
#include 
#include 
#include 

const long size = 302300L;

int main()
{
    std::vector numbers(size);
    std::srand(std::time(0));
    std::generate(numbers.begin(), numbers.end(), std::rand);

    int count3a = 0;
    int count3b = 0;
    int count13 = 0;

    auto Ismod3 = [](int x) -> bool { return x % 3 == 0; };
    auto mod3n13a = [&count3a, &count13](int x) {
        count3a += x % 3 == 0;
        count13 += x % 13 == 0;
    };
    auto mod3n13b = [&count3b, &count13](int x) {
        if (x % 3 == 0) ++count3b; // explicit conditional
        if (x % 13 == 0) ++count13;
    };

    int the3 = std::count_if(numbers.begin(), numbers.end(), Ismod3);
    std::for_each(numbers.begin(), numbers.end(), mod3n13a);
    std::for_each(numbers.begin(), numbers.end(), mod3n13b);

    std::cout << "Count from std::count_if: " << the3 << "\n";
    std::cout << "Count from mod3n13a: " << count3a << ", " << count13 << std::endl;
    std::cout << "Count from mod3n13b: " << count3b << ", " << count13 << std::endl;

    return 0;
}

conclusion

日后写代码,需要注意边界条件,尤其是 依赖于中间状态及转换。需要小心验证,考虑到编译器会对我们的代码进行优化,有可能会产生意料之外的结果。

你可能感兴趣的:(c++,windows,开发语言)