C++11相关应用总结:
示例代码:
// atomic::compare_exchange_weak example:
#include <iostream> // std::cout
#include <atomic> // std::atomic
#include <thread> // std::thread
#include <vector> // std::vector
// a simple global linked list:
struct Node { int value; Node* next; };
std::atomic<Node*> list_head (nullptr);
void append (int val) { // append an element to the list
Node* oldHead = list_head;
Node* newNode = new Node {val,oldHead};
// what follows is equivalent to: list_head = newNode, but in a thread-safe way:
while (!list_head.compare_exchange_weak(oldHead,newNode))
newNode->next = oldHead;
}
int main ()
{
// spawn 10 threads to fill the linked list:
std::vector<std::thread> threads;
for (int i=0; i<10; ++i) threads.push_back(std::thread(append,i));
for (auto& th : threads) th.join();
// print contents:
for (Node* it = list_head; it!=nullptr; it=it->next)
std::cout << ' ' << it->value;
std::cout << '\n';
// cleanup:
Node* it; while (it=list_head) {list_head=it->next; delete it;}
return 0;
}
参考文档:
参考文档:
实例:
Thread.h
#ifndef __THREAD_H__
#define __THREAD_H__
#include <thread>
#include <memory>
class Thread {
public:
virtual ~Thread() {}
void start(std::shared_ptr<Thread> ptr);
protected:
virtual void run() {}
private:
static void invoke(std::shared_ptr<Thread> ptr);
};
#endif //__THREAD_H__
Thread.cpp
#include "Thread.h"
void Thread::start(std::shared_ptr<Thread> ptr) {
if (this == ptr.get()) {
std::thread thd(Thread::invoke, ptr);
thd.detach();
}
}
void Thread::invoke(std::shared_ptr<Thread> ptr) {
if (ptr) {
ptr->run();
}
}
main.cpp
#include <atomic>
#include "Thread.h"
class TestThread : public Thread {
public:
TestThread(int count) : m_count(count) {}
int reduce();
protected:
virtual void run();
private:
std::atomic<int> m_count;
};
int TestThread::reduce() {
return --m_count;
}
void TestThread::run() {
while (m_count > 0) {
m_count--;
}
}
int main() {
for (int i = 0; i < 1000; i++) {
std::shared_ptr<Thread> sp(new TestThread(1000));
sp->start(sp);
std::shared_ptr<TestThread> tsp = std::dynamic_pointer_cast<TestThread>(sp);
if (tsp) {
while (tsp->reduce() > 0);
}
}
return 0;
}
shared_from_this优化版本:
#include <thread>
#include <memory>
#include <atomic>
class Thread : public std::enable_shared_from_this<Thread> {
public:
void start();
protected:
virtual ~Thread() {}
virtual void run() {};
};
void Thread::start() {
auto ptr(shared_from_this());
if (ptr) {
std::thread thd([ptr]() {
ptr->run();
});
thd.detach();
}
}
class TestThread : public Thread {
public:
TestThread(int count) : m_count(count) {}
int reduce();
protected:
virtual void run();
private:
std::atomic<int> m_count;
};
int TestThread::reduce() {
return --m_count;
}
void TestThread::run() {
while (m_count > 0) {
m_count--;
}
}
int main() {
for (int i = 0; i < 1000; i++) {
std::shared_ptr<Thread> sp(new TestThread(1000));
sp->start();
std::shared_ptr<TestThread> tsp = std::dynamic_pointer_cast<TestThread>(sp);
if (tsp) {
while (tsp->reduce() > 0);
}
}
return 0;
}
参考文档:Boost 库 Enable_shared_from_this 实现原理分析
普通使用的优化版本:
#include <thread>
#include <memory>
#include <atomic>
class Thread : public std::enable_shared_from_this<Thread> {
public:
void start();
protected:
virtual ~Thread() {}
virtual void run() {};
};
void Thread::start() {
auto ptr(shared_from_this());
if (ptr) {
std::thread thd([ptr]() {
ptr->run();
});
thd.detach();
}
}
class TestThread : public Thread {
public:
TestThread(int count) : m_count(count) {}
~TestThread() { std::cout << __FUNCTIONW__ << std::endl; }
int reduce();
protected:
virtual void run();
private:
std::atomic<int> m_count;
};
int TestThread::reduce() {
return --m_count;
}
void TestThread::run() {
while (m_count > 0) {
m_count--;
}
}
int main() {
std::make_shared<TestThread>(1000)->start();
//TODO main loop
return 0;
}
注释:
#ifndef _SMART_PTR_
#define _SMART_PTR_
template <class _Ty>
struct inner_ptr {
inner_ptr(_Ty* ptr, int cnt) : rawPtr(ptr), count(cnt) {}
~inner_ptr() {
if (rawPtr != nullptr)
delete rawPtr;
}
_Ty* rawPtr;
int count;
};
template <class _Ty>
class smart_ptr {
private:
typedef struct inner_ptr<_Ty> Iy;
Iy* iyPtr;
public:
smart_ptr(_Ty* ptr = nullptr) {
iyPtr = nullptr;
if (ptr != nullptr)
iyPtr = new Iy(ptr, 1);
}
smart_ptr(const smart_ptr<_Ty>& other) {
if (other.iyPtr != nullptr) {
iyPtr = other.iyPtr;
iyPtr->count++;
} else {
iyPtr = nullptr;
}
}
~smart_ptr() {
if (iyPtr != nullptr)
if (--(iyPtr->count) == 0)
delete iyPtr;
}
const smart_ptr<_Ty>& operator=(const smart_ptr<_Ty>& other) {
if (iyPtr == other.iyPtr)
return (*this);
if (iyPtr != nullptr)
if (--(iyPtr->count) == 0)
delete iyPtr;
if (other.iyPtr != nullptr) {
iyPtr = other.iyPtr;
iyPtr->count++;
} else {
iyPtr = nullptr;
}
return (*this);
}
_Ty* operator->() const {
if (iyPtr != nullptr)
return iyPtr->rawPtr;
else
return nullptr;
}
int use_count() const {
if (iyPtr != nullptr)
return iyPtr->count;
else
return 0;
}
};
#endif //_SMART_PTR_
void main(int argc, char **argv) {
...
{
smart_ptr<Copy> spr1;
{
smart_ptr<Copy> spr(new Copy(236));
spr->print();
spr1 = spr;
}
spr1->print();
}
...
}
上述实现和std::shared_ptr的区别:
1st. 引用计数(_Uses and _Weaks)封装成单独类_Ref_count_base
class _Ref_count_base
{ // common code for reference counting
private:
virtual void _Destroy() = 0;
virtual void _Delete_this() = 0;
private:
_Atomic_counter_t _Uses;
_Atomic_counter_t _Weaks;
2nd. std::shared_ptr的基类_Ptr_base封装有_Ty *_Ptr(raw pointer)和_Ref_count_base指针
// TEMPLATE CLASS _Ptr_base
template<class _Ty>
class _Ptr_base
{ // base class for shared_ptr and weak_ptr
private:
_Ty *_Ptr;
_Ref_count_base *_Rep;
可以理解为:通过std::shared_ptr<_Ty> sp(new _Ty) or std::make_shared<_Ty>(new _Ty), _Ty对象会关联相应的引用计数.
===============================
以下延伸:
//////////////pay attention/////////////
Msg* pMsg = new Msg("hello001");
std::shared_ptr<Msg> sp001(pMsg);
std::shared_ptr<Msg> sp002(pMsg);
std::cout << sp001.use_count() << std::endl; // print 1
std::cout << sp002.use_count() << std::endl; // print 1
//////////////pay attention/////////////
需要注意:每次执行std::shared_ptr<Msg> sp(pMsg)都会为Msg对象创建_Ref_count_base对象(包含引用计数),所以会导致Msg对象的释放错误.
利用shared_ptr实现消息队列的简单实现:
#include <deque>
#include <memory>
#include <string>
#include <functional>
class Msg : public std::enable_shared_from_this<Msg> {
public:
Msg(const std::string& data) : m_data(data) {}
~Msg() { std::cout << "Msg::~Msg" << std::endl; }
std::function<const std::string& ()> registerCallback() {
std::shared_ptr<Msg> self(shared_from_this());
std::function<const std::string& ()> functor = [this, self]() -> const std::string& {
return m_data;
};
return functor;
}
private:
std::string m_data;
};
int main(int argc, char **argv) {
std::deque<std::function<const std::string& ()>> msgque;
for (int i=1; i<=10; i++) {
std::string data = std::string("message").append(std::to_string(i));
std::shared_ptr<Msg> sp = std::make_shared<Msg>(data);
msgque.push_back(sp->registerCallback());
}
#if 1
while (!msgque.empty()) {
auto functor = msgque.front();
msgque.pop_front();
std::string data = functor();
std::cout << "process: " << data << std::endl;
}
#else
std::for_each(msgque.begin(), msgque.end(),
[](const std::function<const std::string& ()>& callback) {
std::string data = callback();
std::cout << "process: " << data << std::endl;
});
msgque.clear();
#endif
return 0;
}
用例说明:
注:使用std::shared_ptr<Msg> self(shared_from_this())而不直接使用std::shared_ptr<Msg> self(this)的原因参考3.0的最后注意事项.
参考文档:
===============================
使用std::shared_ptr<_Ty> & std::enable_shared_from_this<_Ty>的思路:
需要用到异步事件处理的场景。先将事件相关信息封装成类,将事件处理函数以lambda形式通过在事件类内实现而完成注册,且lambda函数通过shared_from_this()初始化的std::shared_ptr管理事件类对象的生存周期。可以理解为事件类对象封装到事件处理回调函数(std::function)。程序注册事件处理函数后,立即返回,待事件触发后调用相关事件处理回调函数。当事件处理回调函数释放时,其管理的事件类对象释放。
事件处理函数(lambda)封装事件对象this指针和指向该事件对象的std::shared_ptr,在lambda函数内可以通过this指针按照事件类内调用原则进行调用,可以通过调用虚函数实现一定程度的扩展。
std::shared_ptr<int> sp1,sp2;
std::weak_ptr<int> wp, wp2;
sp1 = std::make_shared<int> (20); // sp1
wp = sp1; // sp1, wp
std::cout << wp.use_count() << std::endl;
std::cout << sp1.use_count() << std::endl;
sp2 = wp.lock(); // sp1, wp, sp2
sp1.reset(); // wp, sp2
wp2 = wp;
std::cout << wp.use_count() << std::endl;
std::cout << sp2.use_count() << std::endl;
if (!sp1) {
sp1 = wp.lock(); // sp1, wp, sp2
}
std::cout << "*sp1: " << *sp1 << '\n';
std::cout << "*sp2: " << *sp2 << '\n';
参考文档:Boost 库 Enable_shared_from_this 实现原理分析
class Mem {
public:
~Mem();
Mem() : m_str(nullptr), m_len(0) {}
Mem(const char* str, int len);
Mem(const Mem& obj);
Mem(Mem&& obj);
Mem& operator=(Mem&& obj);
private:
int m_len;
char* m_str;
};
Mem::~Mem() {
if (m_str != nullptr) {
delete[] m_str;
}
}
Mem::Mem(const char* str, int len) {
m_str = new char[len + 1];
memcpy(m_str, str, len);
m_str[len] = '\0';
m_len = len;
}
Mem::Mem(const Mem& obj) {
m_str = new char[obj.m_len + 1];
memcpy(m_str, obj.m_str, obj.m_len);
m_str[obj.m_len] = '\0';
m_len = obj.m_len;
}
// move construction
Mem::Mem(Mem&& obj) {
m_str = obj.m_str;
m_len = obj.m_len;
obj.m_str = nullptr;
obj.m_len = 0;
}
// move assignment operator
Mem& Mem::operator=(Mem&& obj) {
std::swap(m_str, obj.m_str);
std::swap(m_len, obj.m_len);
return (*this);
}
void main() {
std::list<Mem> mlist;
mlist.push_back(std::move(Mem("hello", strlen("hello")))); // call move construction
mlist.push_back(std::move(Mem("world", strlen("world"))));
std::map<int, Mem> mp;
mp[0] = std::move(lsclone::Mem("hello", strlen("hello"))); // call move assignment operator
mp[1] = std::move(lsclone::Mem("world", strlen("world")));
}
说明:
1、 auto不能用来声明函数的返回值。但如果函数有一个尾随的返回类型时,auto是可以出现在函数声明中返回值位置。这种情况下,auto并不是告诉编译器去推断返回类型,而是指引编译器去函数的末端寻找返回值类型。在下面这个例子中,函数的返回值类型就是operator+操作符作用在T1、T2类型变量上的返回值类型。
template <typename T1, typename T2>
auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
{
return t1+t2;
}
auto v = compose(2, 3.14);
// v's type is double
2、 auto不能用作函数的形参,如果传递匿名函数,需要使用std::function
#include <functional>
void invoke(std::function<int(int&, int&)> func) {
int a = 10, b = 22;
int sum = func(a, b);
}
void main() {
std::function<int(int&, int&)> swap_func = [](int& a, int& b) -> int {
a ^= b;
b ^= a;
a ^= b;
return (a+b);
};
invoke(swap_func);
}
实例
#include <stdio.h>
class Test {
public:
Test(int a) : data(a) {}
Test(const Test& t);
~Test();
const Test& operator=(const Test& t);
private:
int data;
};
Test::Test(const Test& t) {
data = t.data;
}
Test::~Test(){
printf("%s\n", __FUNCTION__);
}
const Test& Test::operator=(const Test& t) {
data = t.data;
return (*this);
}
Test test() {
Test tt(12);
return tt;
}
int main() {
#if 0
Test t(22);
t = test();
#else
Test t = test();
#endif
return 0;
}
参考文档:
参考文档:
在C++11 之前, 不论是模板类或是模板函数,都只能按其被声明时所指定的样子,接受一组固定数目的模板实参;
C++11 加入新的表示法,允许任意个数、任意类别的模板实参,不必在定义时将实参的个数固定。
template<typename... Values> class tuple;
模板类tuple 的对象,能接受不限个数的typename 作为它的模板形参:
class tuple<int, std::vector<int>, std::map<std::string, std::vector<int>>> someInstanceName
实参的个数也可以是 0,所以class tuple<> someInstanceName 这样的定义也是可以的。
若不希望产生实参个数为0 的变长参数模板,则可以采用以下的定义:
template<typename First, typename... Rest> class tuple;
变长参数的数量可以藉以下的语法得知:
template<typename ...Args> struct SomeStruct
{
static const int size = sizeof...(Args);
}
参考实例:
#include <iostream>
void printf(const char *s)
{
while (*s)
{
if (*s == '%' && *(++s) != '%')
throw std::runtime_error("invalid format string: missing arguments");
std::cout << *s++;
}
}
template<typename T, typename... Args>
void printf(const char* s, T value, Args... args)
{
while (*s)
{
if (*s == '%' && *(++s) != '%')
{
std::cout << value;
printf(*s ? ++s : s, args...); // 即便当*s == '\0' 也会产生调用,以检测更多的类型参数。
return;
}
std::cout << *s++;
}
throw std::logic_error("extra arguments provided to printf");
}
详细介绍参考:C++11标准中文版文档的6.1 变长参数模板
参考网址:C++11中可变参数个数的模板(variadic template)
#include <functional>
class Test {
public:
std::function<int()> set(int a);
private:
int data;
};
std::function<int()> Test::set(int a) {
data = a;
auto fun = [this]() -> int {
return this->data++;
};
return fun;
}
void main() {
Test t1;
auto fun = t1.set(1032);
int a = fun();
}
#include <functional>
class Test {
public:
std::function<int()>* set(int a);
private:
int data;
};
std::function<int()>* Test::set(int a) {
data = a;
auto fun = new std::function<int()>([this]() -> int {
return this->data++;
});
return fun;
}
void main() {
Test t1;
auto fun = t1.set(1032);
int a = (*fun)();
delete fun;
}
#include <functional>
class Test {
public:
void set(int a);
inline int get() { return data; }
std::function<int(int)>* set(std::function<int(int)> func);
private:
int data;
};
void Test::set(int a) {
data = a;
}
std::function<int(int)>* Test::set(std::function<int(int)> func) {
auto fun = new std::function<int(int)>(func);
return fun;
}
void main() {
Test t1;
auto func = [&](int a) -> int {
t1.set(a);
return t1.get();
};
auto fun = t1.set(func);
int a = (*fun)(1023);
delete fun;
int b = func(2048);
}
#include <functional>
class Test {
public:
Test(int a) : data(a) {}
std::function<int(int)> set(int a);
inline void increase(int a) { data += a; }
private:
int data;
};
std::function<int(int)> Test::set(int a) {
data = a;
auto fun = [this](int a) -> int {
this->data = a;
return this->data;
};
return fun;
}
void main() {
Test* pTest = new Test(10);
auto fun = pTest->set(1032);
delete pTest;
pTest = nullptr;
int a = fun(20);
pTest->increase(20); //error
}
lambda匿名函数一般格式: ( params ) -> ret { body }
capture-list can be passed as follows (see below for the detailed description):
[a,&b] where a is captured by value and b is captured by reference.
[this] captures the this pointer by value
[&] captures all automatic variables odr-used in the body of the lambda by reference
[=] captures all automatic variables odr-used in the body of the lambda by value
[] captures nothing
capture使用心得:
参考网址:C++官网 Lambda functions (since C++11)
capture: this
#include <functional>
class A {
public:
virtual void test() = 0;
protected:
//A() { std::cout << "A::A" << std::endl; }
virtual ~A() { std::cout << "A::~A" << std::endl; }
void testA() { std::cout << "A::testA" << std::endl; }
};
class C {
public:
C() { std::cout << "C::C" << std::endl; }
C(const C& other) { std::cout << "C::C copy function" << std::endl; }
~C() { std::cout << "C::~C" << std::endl; }
void testC() const { std::cout << "C::testC" << std::endl; }
};
class B : public A {
public:
B() { std::cout << "B::B" << std::endl; }
~B() { std::cout << "B::~B" << std::endl; }
virtual void test() { std::cout << "B::test" << std::endl; }
void testB() { std::cout << "B::testB" << std::endl; }
void invoke(std::function<void ()>& functor) {
C c1;
functor = [this, c1]() { // const C c1
this->testA();
this->testB();
c1.testC();
};
}
};
int main() {
{
B b1;
std::function<void ()> functor;
{
std::function<void ()> callback;
b1.invoke(callback);
functor = callback;
callback();
}
functor();
}
return 0;
}
打印信息:
B::B
C::C
C::C copy function
C::C copy function
C::~C
C::~C
C::C copy function
A::testA
B::testB
C::testC
C::~C
A::testA
B::testB
C::testC
C::~C
B::~B
A::~A
scopeguard.h
#ifndef scopeguard_h__
#define scopeguard_h__
#include <utility>
namespace sg
{
template <class Fun>
class ScopeGuard {
Fun f_;
bool active_;
public:
ScopeGuard(Fun f)
: f_(std::move(f))
, active_(true) {
}
~ScopeGuard() { if (active_) f_(); }
void dismiss() { active_ = false; }
ScopeGuard(ScopeGuard&& rhs)
: f_(std::move(rhs.f_))
, active_(rhs.active_) {
rhs.dismiss();
}
};
namespace detail {
class ScopeGuardOnExit {};
template <typename Fun>
ScopeGuard<Fun> operator+(ScopeGuardOnExit, Fun&& fn) {
return ScopeGuard<Fun>(std::forward<Fun>(fn));
}
}
}
#define SCOPE_EXIT \
auto ANONYMOUS_VARIABLE(SCOPE_EXIT_STATE) \
= sg::detail::ScopeGuardOnExit() + [&]()
#define CONCATENATE_IMPL(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)
#ifdef __COUNTER__
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str, __COUNTER__)
#else
#define ANONYMOUS_VARIABLE(str) \
CONCATENATE(str, __LINE__)
#endif
#endif // scopeguard_h__
main.cpp
#include <stdio.h>
#include "scopeguard.h"
int test() {
SCOPE_EXIT{
printf("end of test()\n");
};
return 0;
}
void main() {
test();
{
SCOPE_EXIT{
printf("end of main()\n");
};
}
}
参考文档:如何退出函数时再做一些固定的事情(比如释放内存)--scopeguard
=====================================================================
参考文档:
=====================================================================
测试用例
#include <atomic>
#include <memory>
#include <thread>
#include <functional>
#include <map>
#include <list>
#include <vector>
#include <algorithm>
#include <iostream>
template <typename T1, typename T2>
auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
{
return t1+t2;
}
namespace lsclone {
class Mem {
public:
~Mem();
Mem() : m_str(nullptr), m_len(0) {}
Mem(const char* str, int len);
Mem(const Mem& obj);
Mem(Mem&& obj);
Mem& operator=(Mem&& obj);
void set(const char* str, int len);
void show();
private:
int m_len;
char* m_str;
};
Mem::~Mem() {
if (m_str != nullptr) {
delete[] m_str;
}
}
Mem::Mem(const char* str, int len) {
m_str = new char[len + 1];
memcpy(m_str, str, len);
m_str[len] = '\0';
m_len = len;
}
Mem::Mem(const Mem& obj) {
m_str = new char[obj.m_len + 1];
memcpy(m_str, obj.m_str, obj.m_len);
m_str[obj.m_len] = '\0';
m_len = obj.m_len;
}
// move construction
Mem::Mem(Mem&& obj) {
m_str = obj.m_str;
m_len = obj.m_len;
obj.m_str = nullptr;
obj.m_len = 0;
}
// move assignment operator
Mem& Mem::operator=(Mem&& obj) {
std::swap(m_str, obj.m_str);
std::swap(m_len, obj.m_len);
return (*this);
}
void Mem::set(const char* str, int len) {
if (m_str != nullptr) {
delete m_str;
m_str = nullptr;
}
m_str = new char[len + 1];
memcpy(m_str, str, len);
m_str[len] = '\0';
m_len = len;
}
void Mem::show() {
if (m_str != nullptr) {
printf("%s\n", m_str);
}
}
class Mem2 {
public:
Mem2(const char* str, int len) : mObj(str, len) {}
private:
Mem mObj;
};
}
typedef struct _Info {
int data;
}Info;
void func(std::function<int(int&, int&)> swap_func) {
int a = 10, b = 22;
int sum = swap_func(a, b);
}
class A {
public:
virtual void test() = 0; //{ std::cout << "A::test" << std::endl; }
void testA() { std::cout << "A::testA" << std::endl; }
protected:
//A() { std::cout << "A::A" << std::endl; }
virtual ~A() { std::cout << "A::~A" << std::endl; }
};
class B : public A {
public:
B() { std::cout << "B::B" << std::endl; }
~B() { std::cout << "B::~B" << std::endl; }
virtual void test() { std::cout << "B::test" << std::endl; }
void testB() { std::cout << "B::testB" << std::endl; }
};
int main() {
std::shared_ptr<A> spa(new B);
std::shared_ptr<B> spb = std::dynamic_pointer_cast<B>(spa);
if (spb) {
std::cout << spa.use_count() << std::endl; // 2
std::cout << spb.use_count() << std::endl; // 2
}
int arr[] = {1,2,3};
std::for_each(std::begin(arr), std::end(arr), [](int num) {std::cout << num << std::endl;});
auto is_odd = [](int n) {return n%2==1;};
auto pos = std::find_if(std::begin(arr), std::end(arr), is_odd);
if(pos != std::end(arr)) {
std::cout << *pos << std::endl;
*pos += 100;
}
auto is_odd2 = is_odd;
bool oddret = is_odd2(10);
auto swap_func = [](int& a, int& b) -> int {
a ^= b;
b ^= a;
a ^= b;
return (a+b);
};
func(swap_func);
lsclone::Mem2 mm1("hello", strlen("hello"));
auto v = compose<double, double>(2, 3.14);
int a[2] = {15, 20};
int b = 10;
auto sum = [&b](double t1, double t2) -> double { b = 22; return (t1+t2);};
printf("%.2f %d\n", sum(1.2, 0.98), b); // printf b 10 !!!
printf("b: %d\n", b);
std::function<int(int)> lfib = [&lfib](int n) {return n < 2 ? 1 : lfib(n-1);};
auto res = lfib(100);
printf("%d\n", res);
lsclone::Mem m1("string", strlen("string"));
lsclone::Mem m2(m1);
lsclone::Mem m3(std::move(m1));
lsclone::Mem m4(lsclone::Mem("123", 3));
std::list<Info> nlist;
Info f1, f2;
f1.data = 10;
f2.data = 20;
nlist.push_back(f1);
nlist.push_back(f2);
std::list<Info>::iterator listIt = nlist.begin();
for (; listIt != nlist.end(); listIt++) {
(*listIt).data += 5;
}
std::list<int> ilist;
ilist.push_back(12);
ilist.push_back(22);
std::list<int>::iterator iIt = ilist.begin();
for (; iIt != ilist.end(); iIt++) {
*iIt = 6;
}
std::vector<std::string> strVec;
strVec.push_back("hello");
strVec.push_back("world");
strVec.push_back("end");
std::list<lsclone::Mem> mlist;
#if 0
lsclone::Mem eleMem;
for (int i = 0; i<3; i++) {
eleMem.set(strVec[i].c_str(), strVec[i].size());
mlist.push_back(std::move(eleMem));
}
#else
mlist.push_back(std::move(lsclone::Mem("hello", strlen("hello"))));
mlist.push_back(std::move(lsclone::Mem("world", strlen("world"))));
#endif
for (auto it = mlist.begin(); it != mlist.end(); it++ ) {
it->show();
}
for (auto& ele: mlist) {
ele.show();
}
std::map<int, lsclone::Mem> mp;
mp[0] = std::move(lsclone::Mem("hello", strlen("hello")));
mp[1] = std::move(lsclone::Mem("world", strlen("world")));
auto it = mp.find(1);
if (it != mp.end()) {
it->second.show();
it->second.set("end", strlen("end"));
}
std::list<int> list1;
list1.push_back(10);
list1.push_back(20);
list1.push_back(30);
std::for_each(list1.begin(), list1.end(), [](int item){
printf("list item: %d\n", item); });
return 0;
}
参考网址: c++官网for_each函数