`
shfzhzhr
  • 浏览: 70573 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

C++ Template Metaprogramming——一个小型lambda库的实作

阅读更多

Boost里面的lambda库实在是很复杂,因此我对其进行了精简,缩减到300多行代码,只支持+-*/四则运算,虽没有boost中lambda库那么强大,亦可窥其奥妙。下面是lambda库的源码:

 

/*
 * lambda.h
 *
 *  Created on: 2010-12-28
 *      Author: 
 */

#ifndef LAMBDA_H_
#define LAMBDA_H_

#include "boost/tuple/tuple.hpp"
#include "boost/any.hpp"

using namespace boost;

#define CALL_TEMPLATE_ARGS class A, class B, class C, class Env
#define CALL_FORMAL_ARGS A& a, B& b, C& c, Env& env
#define CALL_ACTUAL_ARGS a, b, c, env
#define CALL_ACTUAL_ARGS_NO_ENV a, b, c
#define CALL_REFERENCE_TYPES A, B, C, Env&
#define CALL_PLAIN_TYPES A, B, C, Env

#define LAMBDA_DISABLE_IF_ARRAY1(A1, R1) typename R1::type
#define LAMBDA_DISABLE_IF_ARRAY2(A1, A2, R1, R2) typename R1, R2::type
#define LAMBDA_DISABLE_IF_ARRAY3(A1, A2, A3, R1, R2, R3) typename R1, R2, R3::type

template<class A1, class A2, class A3, class A4>
void do_nothing(A1&, A2&, A3&, A4&) {
}

#define CALL_USE_ARGS \
do_nothing(a, b, c, env)

template<class Base>
class lambda_functor;

template<class Act, class Args>
class lambda_functor_base;

struct null_type {
};

static const null_type constant_null_type = null_type();
#define cnull_type() constant_null_type

enum {
	NONE = 0x00, // Notice we are using bits as flags here.
	FIRST = 0x01,
	SECOND = 0x02,
	THIRD = 0x04,
	EXCEPTION = 0x08,
	RETHROW = 0x10
};

template<bool If, class Then, class Else> struct IF {
	typedef Then RET;
};

template<class Then, class Else> struct IF<false, Then, Else> {
	typedef Else RET;
};

template<class T1, class T2>
struct parameter_traits_ {
	typedef T2 type;
};

template<class T>
struct const_copy_argument {
typedef	typename
	parameter_traits_<
		T,
		typename IF<boost::is_function<T>::value, T&, const T>::RET
	>::type type;
};

// returns a reference to the element of tuple T
template<int N, class T> struct tuple_element_as_reference {
typedef	typename
	boost::tuples::access_traits<
		typename boost::tuples::element<N, T>::type
	>::non_const_type type;
};

template<int N, class Tuple> struct get_element_or_null_type {
typedef	typename
	tuple_element_as_reference<N, Tuple>::type type;
};
template<int N> struct get_element_or_null_type<N, null_type> {
	typedef null_type type;
};

template<int I> struct placeholder;

template<> struct placeholder<FIRST> {

	template<class SigArgs> struct sig {
		typedef	typename get_element_or_null_type<0, SigArgs>::type type;
	};

	template<class RET, CALL_TEMPLATE_ARGS>
	RET call(CALL_FORMAL_ARGS) const {
		BOOST_STATIC_ASSERT(boost::is_reference<RET>::value);
		CALL_USE_ARGS; // does nothing, prevents warnings for unused args
		return a;
	}
};

template<> struct placeholder<SECOND> {

	template<class SigArgs> struct sig {
		typedef	typename get_element_or_null_type<1, SigArgs>::type type;
	};

	template<class RET, CALL_TEMPLATE_ARGS>
	RET call(CALL_FORMAL_ARGS) const {CALL_USE_ARGS; return b;}
};

template<> struct placeholder<THIRD> {

	template<class SigArgs> struct sig {
		typedef	typename get_element_or_null_type<2, SigArgs>::type type;
	};

	template<class RET, CALL_TEMPLATE_ARGS>
	RET call(CALL_FORMAL_ARGS) const {CALL_USE_ARGS; return c;}
};

template<> struct placeholder<EXCEPTION> {

	template<class SigArgs> struct sig {
		typedef	typename get_element_or_null_type<3, SigArgs>::type type;
	};

	template<class RET, CALL_TEMPLATE_ARGS>
	RET call(CALL_FORMAL_ARGS) const {CALL_USE_ARGS; return env;}
};

// select functions -------------------------------
template<class Any, CALL_TEMPLATE_ARGS>
inline Any& select(Any& any, CALL_FORMAL_ARGS) {CALL_USE_ARGS; return any;}

template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( const lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
	return op.template call<
	typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>	(CALL_ACTUAL_ARGS);
}
template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( lambda_functor<Arg>& op, CALL_FORMAL_ARGS) {
	return op.template call<
	typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>	(CALL_ACTUAL_ARGS);
}

class plus_action {};
class minus_action {};
class multiply_action {};
class divide_action {};

#define LAMBDA_BINARY_ACTION(SYMBOL, ACTION_CLASS)  					 \
template<class Args>                                                      \
class lambda_functor_base<ACTION_CLASS, Args> {                           \
public:                                                                   \
  Args args;                                                              \
public:                                                                   \
  explicit lambda_functor_base(const Args& a) : args(a) {}                \
                                                                          \
  template<class RET, CALL_TEMPLATE_ARGS>                                 \
  RET call(CALL_FORMAL_ARGS) const {                                      \
    return select(boost::tuples::get<0>(args), CALL_ACTUAL_ARGS)  \
           SYMBOL                                                         \
           select(boost::tuples::get<1>(args), CALL_ACTUAL_ARGS); \
  }                                                                       \
  template<class SigArgs> struct sig {                                    \
    typedef typename                                                      \
		boost::tuples::element<0,SigArgs>::type type;         			  \
  };                                                                      \
};

LAMBDA_BINARY_ACTION(+,plus_action)
LAMBDA_BINARY_ACTION(-,minus_action)
LAMBDA_BINARY_ACTION(*,multiply_action)
LAMBDA_BINARY_ACTION(/,divide_action)


template<class T>
class lambda_functor: public T {
public:
	typedef T inherited;

	lambda_functor() {}

	lambda_functor(const lambda_functor& l) : inherited(l) {}

	lambda_functor(const T& t) :
		inherited(t) {
	}


	  template<class A>
	  typename inherited::template sig<tuple<A> >::type
	  operator()(A& a) const {
	    return inherited::template call<
	      typename inherited::template sig<tuple<A> >::type
	    >(a, cnull_type(), cnull_type(), cnull_type());
	  }

	  template<class A>
	  LAMBDA_DISABLE_IF_ARRAY1(A, inherited::template sig<tuple<A> >)
	  operator()(A const& a) const {
	    return inherited::template call<
	      typename inherited::template sig<tuple<A> >::type
	    >(a, cnull_type(), cnull_type(), cnull_type());
	  }

	template<class A, class B>
	typename inherited::template sig<tuple<A, B> >::type
	operator()(A& a, B& b) const {
		return inherited::template call<
			typename inherited::template sig<tuple<A, B> >::type
		>(a, b, cnull_type(), cnull_type());
	}

	template<class A, class B>
	LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A, B> >)
	operator()(A const& a, B& b) const {
		return inherited::template call<
			typename inherited::template sig<tuple<A, B> >::type
		>(a, b, cnull_type(), cnull_type());
	}

	template<class A, class B>
	LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A, B> >)
	operator()(A& a, B const& b) const {
		return inherited::template call<
			typename inherited::template sig<tuple<A, B> >::type
		>(a, b, cnull_type(), cnull_type());
	}

	template<class A, class B>
	LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A, B> >)
	operator()(A const& a, B const& b) const {
		return inherited::template call<
			typename inherited::template sig<tuple<A, B> >::type
		>(a, b, cnull_type(), cnull_type());
	}

	template<class A, class B, class C>
	typename inherited::template sig<tuple<A, B, C> >::type
	operator()(A& a, B& b, C& c) const
	{
		return inherited::template call<
			typename inherited::template sig<tuple<A, B, C> >::type
		>(a, b, c, cnull_type());
	}

	template<class A, class B, class C>
	LAMBDA_DISABLE_IF_ARRAY3(A, B, C, inherited::template sig<tuple<A , B , C> >)
	operator()(A const& a, B const& b, C const& c) const
	{
		return inherited::template call<
			typename inherited::template sig<tuple<A , B , C> >::type
		>(a, b, c, cnull_type());
	}
};

#define LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)      \
template<class Arg, class B>                                                 \
inline const                                                                 \
lambda_functor<                                                              \
  lambda_functor_base<                                                       \
    ACTION,                                                                  \
    tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>  \
  >                                                                          \
>                                                                            \
OPER_NAME (const lambda_functor<Arg>& a, CONSTB& b) {                      \
  return                                                                     \
    lambda_functor_base<                                                     \
      ACTION,                                                                \
      tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>\
    >                                                                        \
   (tuple<lambda_functor<Arg>, typename const_copy_argument <CONSTB>::type>(a, b)); \
}

#define LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)      \
template<class A, class Arg>                                                 \
inline const                                                                 \
lambda_functor<                                                              \
  lambda_functor_base<                                                       \
    ACTION,                                                                  \
    tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >        \
  >                                                                          \
>                                                                            \
OPER_NAME (CONSTA& a, const lambda_functor<Arg>& b) {                      \
  return                                                                     \
    lambda_functor_base<                                                     \
      ACTION,                                                                \
      tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >      \
    >                                                                        \
  (tuple<typename CONVERSION <CONSTA>::type, lambda_functor<Arg> >(a, b)); \
}

#define LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONVERSION)    \
template<class ArgA, class ArgB>                                           \
inline const                                                               \
lambda_functor<                                                            \
  lambda_functor_base<                                                     \
    ACTION,                                                                \
    tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                     \
  >                                                                        \
>                                                                          \
OPER_NAME (const lambda_functor<ArgA>& a, const lambda_functor<ArgB>& b) { \
  return                                                                   \
    lambda_functor_base<                                                   \
      ACTION,                                                              \
      tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                   \
    >                                                                      \
  (tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >(a, b));              \
}

#define LAMBDA_BE(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION) 	   \
LAMBDA_BE1(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)      \
LAMBDA_BE2(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)      \
LAMBDA_BE3(OPER_NAME, ACTION, CONSTA, CONSTB, CONST_CONVERSION)

LAMBDA_BE(operator+, plus_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator-, minus_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator*, multiply_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator/, divide_action,const A,const B,const_copy_argument)

typedef const lambda_functor<placeholder<FIRST> > placeholder1_type;
typedef const lambda_functor<placeholder<SECOND> > placeholder2_type;
typedef const lambda_functor<placeholder<THIRD> > placeholder3_type;

placeholder1_type free1 = placeholder1_type();
placeholder2_type free2 = placeholder2_type();
placeholder3_type free3 = placeholder3_type();

placeholder1_type& _1 = free1;
placeholder2_type& _2 = free2;
placeholder3_type& _3 = free3;

#endif /* LAMBDA_H_ */

 

 

在深入理解代码之前,我们先来看一下lambda的使用:

 

//============================================================================
// Name        : lambdatest.cpp
// Author      : 
// Version     :
// Copyright   : 
// Description : Test my lambda, Ansi-style
//============================================================================

#include "lambda.h"
#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
using namespace std;

template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
  typename T::const_iterator pos;
  std::cout << optcstr;
  for (pos=coll.begin(); pos!=coll.end(); ++pos) {
	  std::cout << *pos << ' ';
  }
  std::cout << std::endl;
}


int main() {
	vector<int> intArr;
	intArr.push_back(1);
	intArr.push_back(2);
	intArr.push_back(3);
	intArr.push_back(4);
	intArr.push_back(5);
	//lambda作用于标准库算法
	transform(intArr.begin(),intArr.end(),intArr.begin(),_1*2);
	PRINT_ELEMENTS(intArr);
	//lambda作用于普通运算
	cout<<(_1+_2)(1,2)<<endl;
	return 0;
}

在STL的算法中,我们一般需要自行定义一些仿函数来使用一些算法,而使用lambda库,我们只要使用类似“_1*2”的形式即可使用STL的算法。不妨想象一下,如果我们的lambda库定义了多种多样的运算符,那么我们完全可以省去写仿函数的时间,而直接使用lambda表达式。

好,既然我们都同意lambda库是很有用的,那么现在就来来看看这个小型lambda的实作细则吧o(∩_∩)o !

直观上看,我们的lambda表达式(如上面的_1*2,_1+_2等)是由占位符和表达式组成的,因此我们可以大胆的推测占位符是一些模版类,而占位符支持+,*之类的运算符是因为这些模版类已经重载了这些运算符。

没错,事实就是这样的。

到源码里去(到祖国的大西部去,口号都是一样的)!

我们看到_1,_2,_3是lambda_functor模板类的三个实例。 而lambda_functor则通过宏定义重载了+-*/四个运算符:

 

LAMBDA_BE(operator+, plus_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator-, minus_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator*, multiply_action,const A,const B,const_copy_argument)
LAMBDA_BE(operator/, divide_action,const A,const B,const_copy_argument)

 

  这么easy啊(看到这里,也许你会觉得不过而而),没你想象的那么简单的,这只是一根语法主线而已,事情还要繁杂的多。

 

型别计算与推演:(这才是重点,important!!!

一切还是从头来,拿_1+_2举例,我们对于lambda_functor的+运算宏展开之后的定义如下:

 

 

template<class ArgA, class ArgB>                                          
inline const                                                              
lambda_functor<                                                           
  lambda_functor_base<                                                     
    plus_action,                                                               
    tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                     
  >                                                                        
>                                                                          
operator+ (const lambda_functor<ArgA>& a, const lambda_functor<ArgB>& b) {
  return                                                                  
    lambda_functor_base<                                                  
      plus_action,                                                             
      tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >                 
    >                                                                     
  (tuple<lambda_functor<ArgA>, lambda_functor<ArgB> >(a, b));             
}
 

 

两个参数_1、_2即使参数a和b,加法运算的结果仍然是返回一个lambda_functor对象,我们姑且把这个lambda_functor叫做_0。那么_0(1,2)就是要调用lambda_functor重载的()

运算符了。好,让我们继续前进,我们这里要调用的lambda_functor的方法如下:

 

	template<class A, class B>
	LAMBDA_DISABLE_IF_ARRAY2(A, B, inherited::template sig<tuple<A, B> >)
	operator()(A const& a, B const& b) const {
		return inherited::template call<
			typename inherited::template sig<tuple<A, B> >::type
		>(a, b, cnull_type(), cnull_type());
	}

 lambda_functor的()重载函数继续调用了,其inherited的call函数,这个inherited就我们前面看到的

 

 

lambda_functor_base<                                                     
    plus_action,                                                               
    tuple<lambda_functor<ArgA>, lambda_functor<ArgB> > 
>
 

 

让我们继续展开lambda_functor_base的定义,(是不是快晕了,别着急,马上胜利了^_^)

 

 

template<class Args>                                                      
class lambda_functor_base<plus_action, Args> {                           
public:                                                                   
  Args args;                                                              
public:                                                                  
  explicit lambda_functor_base(const Args& a) : args(a) {}                
                                                                          
  template<class RET, class A, class B, class C, class Env>                                
  RET call(A& a, B& b, C& c, Env& env) const {                                     
    return select(boost::tuples::get<0>(args), a, b, c, env)  
           +
           select(boost::tuples::get<1>(args), a, b, c, env); 
  }                                                                      
  template<class SigArgs> struct sig {                                   
    typedef typename                                                      
		boost::tuples::element<0,SigArgs>::type type;         			
  };                                                                     
};
 

 

看来还要着落在slect函数身上啊:

 

template<class Arg, CALL_TEMPLATE_ARGS>
inline typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
select ( const lambda_functor<Arg>& op, CALL_FORMAL_ARGS ) {
	return op.template call<
	typename Arg::template sig<tuple<CALL_REFERENCE_TYPES> >::type
>	(CALL_ACTUAL_ARGS);
}
 

 

这里是的op参数是什么呢? 就是我们上面的_1,这里继续调用了_1的call函数,而_1的的类型定义是这样的:

 

typedef const lambda_functor<placeholder<FIRST> > placeholder1_type;

 

 因此会调用placeholder<FIRST>的call方法:

 

template<> struct placeholder<FIRST> {

	template<class SigArgs> struct sig {
		typedef	typename get_element_or_null_type<0, SigArgs>::type type;
	};

	template<class RET, CALL_TEMPLATE_ARGS>
	RET call(CALL_FORMAL_ARGS) const {
		BOOST_STATIC_ASSERT(boost::is_reference<RET>::value);
		CALL_USE_ARGS; // does nothing, prevents warnings for unused args
		return a;
	}
};
 

 

ok,placeholder<FIRST>为我们选取了第一个参数a,也就是(1,2)中的1。

也就是说_0(1,2)最后将转化成1+2。好了,参数的推演我们已经很清楚了。

再来看先返回值的推演,我为了使得这个lambda库的规模尽可能小,对返回值的推演做了简化,返回值主要是通过sig这个内嵌结构推演出来的。我们看下sig的定义:

template<class SigArgs> struct sig {                                    
    typedef typename                                                      
		boost::tuples::element<0,SigArgs>::type type;         			  
  }; 
 

在这里我们只是简单的返回了第一个参数的类型。

 

ok,说完了。关于boost的lambda库,我将在后续的文章中陆续详细写明。

 

 

 

 

分享到:
评论
1 楼 iwobz 2011-10-12  
大哥,这真是你自己写的吗?我太崇拜你了

相关推荐

    C++ Template Metaprogramming

    本资源——"C++ Template Metaprogramming"——提供了一个深入探讨这一领域的英文版指南。 模板是C++语言中的一个关键特性,它允许我们定义函数和类的通用模板,然后在不同类型的参数上实例化它们。模板元编程则是...

    The connection between C template metaprogramming and functional programming

    本文将深入探讨C++模板元编程(Template Metaprogramming, TMP)与函数式编程(Functional Programming, FP)之间的联系。通过分析博士论文《C++模板元编程与函数式编程的联系》中的内容,我们可以更清晰地理解这两...

    C++ TEMPLATE

    C++ 模板是编程语言中的一个重要特性,它允许程序员创建泛型代码,即能够处理多种数据类型的代码。模板在 C++ 中分为两种主要类型:函数模板和类模板。 1. **函数模板**: 函数模板是为编写能够处理不同类型参数的...

    C++编程惯用法——高级程序员常用方法和技巧.

    Boost库中的 MPL(Metaprogamming Library)是模板元编程的一个典型应用。 八、C++11及其后续标准的新特性 从C++11开始,语言引入了许多新特性,如Lambda表达式、右值引用、auto关键字、move语义、类型推断等,这些...

    C++编程惯用法——高级程序员常用方法和技巧

    1. **STL(Standard Template Library)标准模板库**:STL是C++的核心组成部分,包括容器(如vector、list、set等)、迭代器、算法和函数对象。理解如何有效地使用STL可以极大地提高代码的可读性和性能。 2. **模板...

    C++编程惯用法——高级程序员常用方法和技巧.rar

    2. **STL(Standard Template Library)**:STL是C++标准库的一部分,包含容器(如vector、list、map等)、迭代器、算法和函数对象,极大地提高了代码的复用性和效率。 3. **智能指针(Smart Pointers)**:为了解决...

    C++标准库第二版

    C++11是C++语言的一个重大更新,引入了许多新特性以提升效率和可读性。这些包括: 1. 右值引用(Rvalue References):用于实现移动语义(Move Semantics),提高对象拷贝和构造的效率。 2. 模板元编程(Template ...

    C++ 标准程序库 侯捷版本 PDF

    《C++标准程序库》是C++编程领域的一本经典之作,由侯捷翻译的简体完整版,深受广大C++程序员的欢迎。这本书详细介绍了C++标准库的各个方面,对于深入理解和高效使用C++语言至关重要。以下是该书涉及的一些核心知识...

    C++primer中文第五版

    模板元编程(Template Metaprogramming)是C++的一个独特特性,它允许在编译时进行计算。这种技术可以用来创建高度灵活和高效的库,比如Boost库中的很多组件就是基于模板元编程实现的。 在《C++ Primer 中文第五版...

    《C++编程思想(Thinking in C++)》

    此外,C++的模板元编程(Template Metaprogramming)技术可以在编译时执行计算,进一步提升了程序效率。 异常处理是C++中的另一个关键知识点。它提供了一种处理运行时错误的方式,允许程序员在可能出现错误的地方抛...

    C++_C11.rar

    《C++_C11.rar》是一个压缩包文件,其中包含了一份重要的C++开发资源——一个名为"C++_C11.chm"的CHM格式手册。CHM是微软的“ Compiled HTML Help”文件,是一种方便用户快速查找和学习信息的电子文档格式。这份手册...

    c++20标准_c++20标准_

    C++20是C++编程语言的一个重大更新,它引入了一系列新特性,旨在提升效率、可读性以及并发处理能力。以下是对C++20标准的一些关键知识点的详细阐述: 1. **模块(Modules)**:C++20引入了模块机制,允许程序员将...

    C++标准程序库自修教程与参考手册

    异常处理(exception handling)是C++中另一个重要的概念,用于处理程序运行时可能出现的错误。通过理解try、catch和throw关键字的使用,你可以编写出更健壮的代码,更好地处理程序的异常情况。 模板(templates)...

    The Boost C++ Libraries 中文版 chm

    Boost库是C++编程语言的一个开源库集合,旨在提升C++的标准库功能,为开发人员提供了大量高质量、经过充分测试的代码组件。下面,我们将深入探讨Boost库的关键知识点。 1. **Boost库的概述**:Boost库由C++社区开发...

    深入理解C++11:C++11新特性解析与应用(62M高清扫描版)

    C++11是C++语言的一个重大更新,引入了许多现代化的编程特性,提升了代码的效率、可读性和安全性。 首先,C++11引入了类型推断(Type Inference)机制,即`auto`关键字。在C++11之前,声明变量时需要显式指定类型,...

    C++官方文档

    C++是一种强大的、通用的编程语言,以其面向对象特性、高效性能和丰富的库支持而闻名。C++官方文档,如2015年8月8日版本的cppreference-doc,是学习和理解C++语法、类库以及编程实践的重要资源。这份文档详细地介绍...

    C++11标准文档英文版

    C++11是C++编程语言的一个重要里程碑,它在2011年由国际标准化组织(ISO)发布,正式名称为ISO/IEC 14882:2011。这个版本引入了大量的新特性,极大地扩展了C++的功能,并提升了其现代性和效率。下面我们将深入探讨...

    C++编程思想(pdf)

    此外,书中还会介绍STL(Standard Template Library,标准模板库),这是C++的一个强大工具箱,包括容器(如vector, list, set等)、迭代器、算法和函数对象等,它们极大地提高了C++程序员的生产力。 异常处理是C++...

    极简风格快速处理序列化与反序列化 C++ 11 C++20 测试及代码实现工程文件

    具体实现上,可能会使用C++的流I/O库(iostream)来读写二进制数据,或者使用Boost库的serialization模块,这是一个强大的序列化库,支持多种数据格式。另外,C++ 17引入的std::filesystem库也可以用来处理文件操作...

    C++设计新思维_C++_

    1. 泛型编程:泛型编程是C++中的一个重要概念,它允许编写不依赖于特定数据类型的代码。通过模板(templates)实现,可以创建通用的函数和类,提高代码的重用性。例如,`std::vector` 和 `std::sort` 都是泛型编程的...

Global site tag (gtag.js) - Google Analytics