Add list of content

Add part of sample code.
This commit is contained in:
Wu Ye 2013-03-12 23:40:34 +08:00
commit 758bc2aefe
10 changed files with 1099 additions and 0 deletions

22
.gitattributes vendored Normal file
View File

@ -0,0 +1,22 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

163
.gitignore vendored Normal file
View File

@ -0,0 +1,163 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

705
CppTemplateTutorial.cpp Normal file
View File

@ -0,0 +1,705 @@
#include "stdafx.h"
#include <vector>
#define WRONG_CODE_ENABLED 0
// 0. Basic Form
namespace _0
{
template <typename T> // Old fasion: template <class T>
class ClassA
{
T a;
T* b;
T foo();
void foo2(T const&);
};
template <int Sz>
class ClassB
{
int arr[Sz];
};
size_t a = sizeof(ClassB<3>);
size_t b = sizeof(ClassB<7>);
template <typename T> void FunctionA(T const& param)
{
}
template <typename T> T FunctionB()
{
return T();
}
}
// 1.1 Nested in Class
namespace _1_1
{
template <typename T> // Old fasion: template <class T>
class ClassA
{
T a;
T* b;
T foo();
template <typename U> void foo2(T const&, U const&);
};
}
// 1.2 Instanciating 1
namespace _1_2
{
_1_1::ClassA<int> a;
#if WRONG_CODE_ENABLED
_1_1::ClassA<WhatTheFuck> b; // Wrong
_1_1::ClassA c; // Wrong
#endif
}
// 1.3 Instanciating 2
namespace _1_3
{
template <typename T>
class ClassB
{
T* a;
};
template <typename T>
class ClassC
{
T a;
};
struct StructA; // Declared but not be defined
ClassB<StructA> d; // Right
#if WRONG_CODE_ENABLED
ClassC<StructA> e; // Wrong
#endif
}
// 1.4 Specialization, Partial Specialization, Full Specialization
namespace _1_4
{
// Prototype of Templates I: Single Parameter
template <typename T> class ClassD
{
int a;
};
// Specialization: Write a pattern for matching
template <> class ClassD<int> // 1. template <> 2. ClassD<int>
{
int b;
};
template <> class ClassD<float>
{
int c;
};
// Partial-Specialization: A partial pattern for matching
template <typename T> class ClassD<T*> // 1. template <typename T> 2. ClassD<T*>
{
int d;
};
template <> class ClassD<int*> // 1. template <> 2. ClassD<T*>
{
int e;
};
// Question:
// ClassD<int>::?
// ClassD<float>::?
// ClassD<double>::?
// ClassD<double*>::?
// ClassD<int*>::?
// ClassD<int const*>::?
// Prototype of Templates II: Multiple Parameter
template <typename T, typename U> class ClassE
{
int a;
};
template <typename T, typename U> class ClassE<T, U*>
{
int b;
};
template <typename T> class ClassE<T, int>
{
int c;
};
template <typename T> class ClassE<T, int*>
{
int d;
};
template <typename U> class ClassE<int, U>
{
int e;
};
template <> class ClassE<int, int>
{
int f;
};
// Question:
// ClassE<float, double>::?
// ClassE<float, int>::?
// ClassE<int, float>::?
// ClassE<int, int*>::?
// ClassE<int, int>::?
}
// 2.1 Function Specialization
namespace _2_1
{
// Overload is enabled but no partial-specialization
template <typename T> void foo(T const& x) {}
template <typename T> void foo(T& y) {}
void foo(int&) {}
void foo(int) {}
// Specialization or Overloading
template <> void foo<bool>(bool const& x) {}
// Overloading
template <typename T> void foo(T const*) {}
template <typename T, typename U> void foo2(T const&, U const&);
#if WRONG_CODE_ENABLED
template <typename U> void foo2<int, U>(int const&, U const&);
template <typename T, typename U> void foo2<T, U>(int const&, U const&);
#endif
// Overloading - Looks like partial specification
template <typename U> void foo2(int const&, U const&);
template <typename T, typename U> void foo2(T const*, U const&);
// Don't forgot
// T foo(...);
// Specialize types which cannot be inferred by parameter
template <typename UninferableT, typename InferableT>
UninferableT foo3(InferableT const&) { return UninferableT(); }
void test()
{
int x = 5;
float y = 10.0f;
foo(y);
int const z = 5;
foo(z);
foo(true);
foo3<int>(0.0f); // Specialize types which is uninferable.
#if WRONG_CODE_ENABLED
foo(3); // Ambigous
foo(x); // Ambigous
#endif
}
}
// 2.2 Example: Derived from template.
namespace _2_2
{
template <typename T>
class ClassA
{
T x;
};
template <typename T>
class ClassB
{
T* x;
};
template <typename T>
class ClassC: public ClassB<T>
{
T* x;
};
ClassC<int> a;
#if WRONG_CODE_ENABLED
class ClassC: public ClassA<ClassC>
{
};
#endif
class ClassD: public ClassB<ClassD>
{
};
// ClassC =??= ClassD
}
// 3.1 Meta Switch-Case/If-Then-Else via Specialization
namespace _3_1
{
bool equal(int a, int b)
{
return a == b;
}
// meta functions:
// bool equal0(TypeA, TypeB)
// {
// return false;
// }
// bool equal1(TypeA, TypeA)
// {
// return true;
// }
// equal(A, A) == equal1(A, A) == true
// euqla(A, B) == equal0(A, B) == false
template <typename T, typename U>
class Equal
{
public:
static bool const value = false;
};
template <typename T>
class Equal<T, T>
{
public:
static bool const value = true;
};
bool x = Equal<int, float>::value;
bool y = Equal<int, int>::value;
}
// 3.2 SFINAE: Substitution Failure Is Not An Error.
namespace _3_2
{
class ClassA
{
};
template <int Sz> struct Mark
{
char _[Sz];
};
#if WRONG_CODE_ENABLED
template <typename T>
Mark<1> TestIncrementAdd(T const& v)
{
T tmp = v;
++tmp;
return Mark<1>();
}
template <typename T>
Mark<2> TestIncrementAdd(T const& v)
{
return Mark<2>();
}
bool a = TestIncrementAdd( ClassA() ) ) == sizeof(Mark<1>);
#endif
// Right case: From Wiki
class ClassB
{
public:
typedef int Marker;
};
template <typename T> void test(typename T::Marker) { }
template <typename T> void test(T) { }
void DoTest()
{
test<ClassB>(10); // Call #1.
test<int>(10); // Call #2. SFINAE for test(T::Marker).
}
}
// 3.3 Application: Type Traits
namespace _3_3
{
template <typename T, typename U> class is_same;
template <typename B, typename D> class is_base_of;
// is_base_of
// 1. B is class, D is also class.
// 2. D* could be convert to B*
// 3. B != D
// Fundamentals
typedef char Accepted;
typedef int Rejected;
class B
{
};
class D: public B
{
};
class D2: public D
{
};
// Type is a class
template <typename T>
class is_class
{
private:
// SFINAE
template <typename U> static Accepted test( int U::* );
template <typename U> static Rejected test(...);
public:
static const bool value = sizeof( test<T>(0) ) == sizeof(Accepted);
};
bool a = is_class<int>::value;
bool b = is_class<B>::value;
// B* could be convert to D*
template <typename Source, typename Dest>
class Convertible
{
private:
// Not SFINAE
static Accepted test(Dest*);
static Rejected test(...);
public:
static const bool value = sizeof( test(static_cast<Source*>(NULL)) ) == sizeof(Accepted);
};
bool c = Convertible<B, D>::value;
bool d = Convertible<D, B>::value;
bool e = Convertible<B, int>::value;
// B != D
using _3_1::Equal;
template <typename Base, typename Derived>
class is_base_of
{
public:
static bool const value =
is_class<Base>::value &&
is_class<Derived>::value &&
Convertible<Base, Derived>::value &&
!Equal<Base, Derived>::value;
};
bool f = is_base_of<B, D2>::value;
bool g = is_base_of<D2, D>::value;
bool h = is_base_of<B, int>::value;
bool i = is_base_of<float, int>::value;
// Questions:
// remove_reference
// remove_pointer
// remove all qualifiers
}
// 3.4 Application: "Recursive" and Meta-Programming
namespace _3_4
{
// sum a, a+1, ..., b-1, b
int basic_algo(int a, int b)
{
int result = 0;
for (int i = a; i <= b; ++i)
{
result += i;
}
return result;
}
// Template could not support variable
// sum [a, b] without variable
int recursive_algo(int a, int b)
{
if (a == b)
{
return b;
}
return a + recursive_algo(a+1, b);
}
// Translate to meta-programming
template <int a, int b>
class MetaSum
{
public:
static int const value = MetaSum<a+1, b>::value + a;
};
template <int a>
class MetaSum<a, a>
{
public:
static int const value = a;
};
int a = MetaSum<1, 10>::value;
}
// 3.5 Application: Meta-Fibonacci
namespace _3_5
{
template <int Index>
class Fibonacci
{
public:
static int const value = Fibonacci<Index - 1>::value + Fibonacci<Index - 2>::value;
};
template <>
class Fibonacci<0>
{
public:
static int const value = 0;
};
template <>
class Fibonacci<1>
{
public:
static int const value = 1;
};
int a = Fibonacci<8>::value;
}
// 4 Directive word: typename and template
namespace _4
{
// typename T::type x;
// ??? typename ???
// typename T::template U<type> x;
// ??? template ???
class ClassA
{
public:
typedef int NestedType;
};
class ClassB
{
public:
typedef ClassA::NestedType NestedType;
};
template <typename T>
class ClassC
{
public:
#if WRONG_CODE_ENABLED
typedef T::NestedType NestedType;
#endif
typedef typename T::NestedType NestedType;
typedef typename std::vector<T>::iterator iterator;
};
class ClassD
{
public:
template <typename U, typename V> class NestedType;
};
template <typename T>
class ClassE
{
public:
template <typename U> class NestedType;
};
template <typename T, typename U>
class ClassF
{
#if WRONG_CODE_ENABLED
typedef typename T::NestedType<U> NestedType;
#endif
typedef typename T::template NestedType<U, int> NestedType;
typedef typename ClassE<T>::template NestedType<U> NestedType2;
};
ClassC<ClassB> a;
ClassF<ClassD, float> b;
}
// 5.1 How to Construct Meta Operators
namespace _5_1
{
// Expression = Value/Data Structure + Operator/Operations
// Value in Templates:
// Integral Constant (bool, char, unsigned, ...)
// Type (typename)
// 1. Trick: Constant <--> Type
template <int i>
class int_
{
public:
static int const value = i;
};
int a = int_<5>::value;
// This trick could work with overloading
template <typename T>
void Do(T* obj, int_<2>)
{
}
template <typename T>
void Do(T* obj, int_<1>)
{
}
void foo()
{
Do( static_cast<int*>(nullptr), int_<1>() );
}
template <typename T, int i> void DoAnotherWay(T* obj)
{
}
// Boolean is more useful than integral in general.
template <bool v>
class bool_
{
public:
static bool const value = v;
};
typedef bool_<true> true_;
typedef bool_<false> false_;
#if WRONG_CODE_ENABLED
// Aha, function cannot support partial specialization.
template <typename T> void DoAnotherWay<T, 1>(T* obj) {}
template <typename T> void DoAnotherWay<T, 2>(T* obj) {}
#endif
// 2. Operators:
// add
template <typename T, typename U>
class add_
{
public:
typedef int_<T::value + U::value> type;
static int const value = type::value;
};
#if WRONG_CODE_ENABLED
// conflict
template <int x, int y>
class add_
{
public:
typedef int_<x+y> type;
static int const value = type::value;
};
#endif
template <int x, int y>
class add_c
{
public:
typedef int_<x+y> type;
static int const value = type::value;
};
typedef add_< int_<2>, int_<3> >::type sum;
int b = sum::value;
typedef add_< int_<2>, int_<3> >::type sum_c;
int c = sum_c::value;
// another solution
template <typename T, typename U>
class add2_: public int_<T::value+U::value>
{
};
int d = add2_< int_<2>, int_<3> >::value;
// Other operators: sub, not, or, and ...
}
// 5.2 Example of Meta Programming: Meta-Vector
namespace _5_2
{
// Array: elem[count]
// Meta Array ?
// Recursively Definition
// 'Null' terminated
template <typename HeadT, typename TailT>
class pair_
{
typedef HeadT head;
typedef TailT tail;
};
class Nil;
// Try Use It to Definition
typedef pair_< int, pair_<float, pair_<double, Nil> > > vector_3;
template <typename T0, typename T1 = Nil, typename T2 = Nil, typename T3 = Nil>
class make_vector_
{
typedef pair_< T0, make_vector_<T1, T2, T3> > type;
};
template <>
class make_vector_<Nil, Nil, Nil, Nil>
{
typedef Nil type;
};
template <typename T0, typename T1 = Nil, typename T2 = Nil, typename T3 = Nil>
class vector_: public make_vector_<T0, T1, T2, T3>::type
{
};
typedef vector_<double, float, int> vector3;
// Let's meta-program further
//
// push_back ? tip: push_back<Vector, Element>::type
// pop ?
// find ?
// size ?
}
// 6.1 Template-Template Class
// 6.2 High order function, closure and STL allocator rebind
int _tmain(int argc, _TCHAR* argv[])
{
return 0;
}

20
CppTemplateTutorial.sln Normal file
View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppTemplateTutorial", "CppTemplateTutorial.vcxproj", "{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}.Debug|Win32.ActiveCfg = Debug|Win32
{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}.Debug|Win32.Build.0 = Debug|Win32
{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}.Release|Win32.ActiveCfg = Release|Win32
{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{E86AB3E9-316E-4D00-BBA3-B7CEDFA99D62}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CppTemplateTutorial</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CppTemplateTutorial.cpp" />
<ClCompile Include="stdafx.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="targetver.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CppTemplateTutorial.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

36
ReadMe.md Normal file
View File

@ -0,0 +1,36 @@

# C++ Template 进阶指南
## 0. 前言
## 1. Template的基本语法
###1.1 Template Class的基本语法
###1.2 Template Function的基本语法
###1.3 整型也可是Template参数
###1.4 类中类:灵活的模板定义
## 2. 模板世界的If-Then-Else特化与偏特化
###2.1 实例化/特化类模板:从类模板到可以定义变量的具体类
###2.2 类模板的匹配规则:特化与部分特化
###2.3 函数模板的重载、特化与部分特化
###2.4 技巧单元:模板与继承
## 3 拿起特化的武器,去写程序吧!
###3.1 利用模板特化规则实现If-Then-Else与Switch-Case
###3.2 特化可以有多个选择:替换失败并不是一个错误,只是一种可能
###3.3 技巧单元:获得类型的属性 ———— 类型萃取Type Traits
## 4 用模板写程序吧!骚年!
## 4.1 模板上的递归
## 4.2 实战单元元编程的Fibonacci数列
## 4.3 技巧单元typename与template的另一种用法
## 4.4 实战单元:撰写你自己的元编程“函数”库
## 4.5 实战单元:实现元编程上的数据结构 ———— 以Vector为例
## 5 关于模板,你还需要知道的其它常识
###5.1 Template-Template Class
###5.2 技巧单元:高阶函数 ———— 从函数到函数的组合
###5.3 实战单元STL中的Allocator Rebinder
## 6 结语

8
stdafx.cpp Normal file
View File

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// CppTemplateTutorial.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

15
stdafx.h Normal file
View File

@ -0,0 +1,15 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

8
targetver.h Normal file
View File

@ -0,0 +1,8 @@
#pragma once
// Including SDKDDKVer.h defines the highest available Windows platform.
// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
#include <SDKDDKVer.h>