我们的最终目标是在模板实例化的位置上捕捉并指出违反概念的错误。正如D&E[2]所指出的,可以通过在函数模板上测试所有要求来捕获错误。实际上如何测试要求(特定的有效表达式)是一件微妙的事情,因为我们希望代码被编译 --- 但不执行。我们的方法是在一个单独的函数中测试这些要求,这个函数被赋值给一个函数指针。这种情形下,编译器将实例化这个函数,但不会真正调用它。此外,一个优化的编译器还会将指针赋值作为"死代码"而删掉(虽然这个赋值操作在运行期的代价是非常微不足道的)。你可能会想编译器会不会一开始就跳过语义分析和约束函数的编译,从而使我们的函数指针技术不起作用。这是不可能的,由于删除无用代码和函数是编译器最后一步的工作。我们已经在 GNU C++, Microsoft Visual C++, 和多个基于 EDG 的编译器(KAI C++, SGI MIPSpro)上验证了函数指针的技术。以下代码示范了如何把这种技术应用于 std::stable_sort() 函数:
template <class RandomAccessIterator>
void stable_sort_constraints(RandomAccessIterator i)
{
typename std::iterator_traits<RandomAccessIterator>
::difference_type n;
i += n; // 检查 RandomAccessIterator 的要求
...
}
template <class RandomAccessIterator>
void stable_sort(RandomAccessIterator first, RandomAccessIterator last)
{
typedef void (*fptr_type)(RandomAccessIterator);
fptr_type x = &stable_sort_constraints;
...
}
通常会有一大堆要求需要检查,对于程序库的作者来说,为每一个公有函数编写象 stable_sort_constraints() 一样的约束函数是一件很烦琐的事情。为此,我们按照相应的概念的定义,将一组有效表达式集合起来。对于每个概念,定义一个概念检查类模板,以要检查的类型作为模板参数。这些类含有一个 contraints() 成员函数,负责测试概念所要求的所有有效表达式。约束函数中使用到的对象,如 n 和 i, 则声明为概念检查类的数据成员。
template <class Iter>
struct RandomAccessIteratorConcept
{
void constraints()
{
i += n;
...
}
typename std::iterator_traits<RandomAccessIterator>
::difference_type n;
Iter i;
...
};
我们还可以用这种函数指针机制来引起约束函数的实例化,只不过现在换成了成员函数指针。为了库更加易于执行概念检查,我们将成员函数指针机制包装在一个名为 function_requires() 的函数中。以下代码片断示范了如何使用 function_requires() 来确认迭代器是一个 RandomAccessIterator随机迭代器。
template <class Iter>
void stable_sort(Iter first, Iter last)
{
function_requires< RandomAccessIteratorConcept<Iter> >();
...
}
function_requires() 的定义如下。其中 Concept 为已实例化的概念检查类。我们将约束成员函数的地址赋值给函数指针 x, 这将引起约束函数的实例化,并检查概念的有效表达式。然后我们通过将 x 赋值给 x 来避免编译器的无用变量警告,并将这些都包装在一个 do-while 循环中以防止名字冲突。
template <class Concept>
void function_requires()
{
void (Concept::*x)() = BOOST_FPTR Concept::constraints;
ignore_unused_variable_warning(x);
}
分享到:
相关推荐
这个是关于c++的几种并发模型,主要在于并发的概念和思想。
常用数据结构(线性表、各类链表、散列表、栈和队列、树形结构、图型结构)的C++模板类方式实现, linux环境中通过编译测试(包含makefile和vscode工程文件) 仅供参考和交流学习,欢迎批评指正~
第二部分说明了如何建立抽象的概念及其策略,并研究了C++对象模型。书中带有大量的代码实例,使读者不仅能够从理论上得以提高,而且还能够轻松地在实践中应用。。。 本书适用于C++程序员,也可供对面向对象程序设计...
本书以帮助读者掌握C++面向对象高效编程方法为目的,详细...第二部分说明了如何建立抽象的概念及其策略,并研究了C++对象模型。书中带有大量的代码实例,使读者不仅能够从理论上得以提高,而且还能够轻松地在实践中应用
华为内部员工C++中级培训教材 ... 本课程主要是更进一步探讨一下C++一些基本模型的应用,加深对概念的理解,由于课程时间有限,C++,模型和内容又如此之多,对任何一个模型都无法深入进去,所以只能泛泛而谈。
第二部分说明了如何建立抽象的概念及其策略,并研究了C++对象模型。书中带有大量的代码实例,使读者不仅能够从理论上得以提高,而且还能够轻松地在实践中应用。 本书适用于C++程序员,也可供对面向对象程序设计感...
C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制),而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以...
ODBC基本概念 ADO对象访问模型 ADO与ODBC的区别 MFC中相关类和ADO类库简介 CRecordSet类 CDatabase类 CRecordView类 VC++中调用ADO的常用方法 Visual C++数据库编程实战 VC++演示ODBC...
从逻辑层次来看,在STL中体现了泛型化程序设计的思想,引入了诸多新的名词,比如像需求requirements,概念concept,模型model,容器container,算法algorithmn,迭代子iterator等。与OOPobject-oriented ...
作者:Stanley B.Lippman,Josee Lajoie/著 ... 对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使本书成为C++初学者的最佳指南;对于中高级程序员,本书也是不可或缺的参考书。
WinMain()函数、MFC消息映射机制、API文件操作、MFC文件操作、创建位图对象、模态对话框、菜单的创建、工具栏的使用、状态栏的创建、进程和线程的基本概念、Win32的进程处理、Win32的线程处理、MFC的线程处理、线程...
与传统的C++教材相比,本书对基本概念和技术的介绍更为深入,为你编写实用、正确、易维护和有效的代码打下坚实的基础。 ·强调现代C++编程风格。本书从开篇就介绍现代C++程序设计技术,并揭示了大量关于如何使用...
从概念上看,模型是用数学方程对真实事物的抽象和模拟。比如一个电机模型就是对真实电机模拟,它具有电机的特性:给定一个电压可以得到一定的转速,同时它又是抽象的,我们只关心需要的参数,而忽略不重要的参数,...
(1)概念:包括程序设计的基本概念;程序设计语言的基本语法规则;常用数据形式、常用简单算法。 (2)方法:包括根据问题模型,使用结构化思想设计程序的方法;使用程序设计集成开发环境方法。 (3)实践:能够...
本文从C++语言模型入手,探讨对象模型的塑造过程。从一 个具体的例子着手,针对VS.NET集成的C++编译器的编译结果,对其进行反汇编,从而揭示出代码后面编译器所作的许多工作,以使读者对类的构造、存 储、数据...
计算机编程的概念技术模型
本书详细地介绍了从“应用领域”到“方案领域”的C++设计实现方法,以及开发者在设计思考和设计实践过程中需要用到的记法、图表和设计模型。在读完这本书以后,读者将会了解如何根据应用领域的共同性和差异性分析...
对C++基本概念和技术全面而且权威的阐述,对现代C++编程风格的强调,使本书成为C++初学者的最佳指南;对于中高级程序员,本书也是不可或缺的参考书。本书的前言阐述了 第4版和前一版的不同之处。 【目录信息】 第1...
与传统的C++教材相比,本书对基本概念和技术的介绍更为深入,为你编写实用、正确、易维护和有效的代码打下坚实的基础。 ·强调现代C++编程风格。本书从开篇就介绍现代C++程序设计技术,并揭示了大量关于如何使用...
5.23.1 使用MFC方法定制控件必备的几个基本概念 259 5.23.2 定制自定义控件的3种常见方法 260 5.24 Visual C++ 2010 SysLink控件简介与开发 260 5.25 Visual C++ 2010 Split Button控件简介与开发 261 5.26 Visual ...