最近我正在阅读“编程元素”一书,我在源代码中找到了这个宏。
我在这里也发现了一个类似的问题,但它与此完全不同。
以下是关于此的一段代码:
#define requires(...)
template<typename T>
requires(Regular(T))
void construct(T& p)
{
// Precondition: $p$ refers to raw memory, not an object
// Postcondition: $p$ is in a default-constructed state
new (&p) T();
}
我想知道“#define需要(...)”的意思,以及为什么要这样写。
答案 0 :(得分:3)
#define requires(...)
扩展为空。
技术:省略号...
允许此宏采用可变数量的参数,这对于使用直接用逗号作为参数的模板表达式是必要的。
它显然用于表示对模板的要求,例如未来的C ++“概念”。但是,小写名称很容易与其他东西发生冲突(宏不尊重作用域),如果C ++获得概念支持,那么使用它的代码无论如何都必须进行双重检查,因此它有一些严重的缺点并且没有优势普通评论。
答案 1 :(得分:2)
这是某人定义先决条件的方式。 define创建一个宏,它接受任意数量的参数并且不会产生代码。然后,他们使用自己的命名法来指定所需的要求。
当它被添加到c ++时,他们可能打算使用它来支持概念或其他合同系统
答案 2 :(得分:2)
本书Elements of Programming由STL之父Alexander Stepanov和Paul McJones撰写。
{1}}表示法在第1章中描述。当前必要的实现 - #define requires(...)
宏 - 在附录B.2中描述。第13页给出了它在书中所代表内容的语义描述(省略了两个脚注):
abstract 过程按类型和常量值进行参数化,并对这些参数有要求。我们使用函数模板和函数对象模板。参数遵循
template
关键字,由typename
引入,用于类型和int
或其他整数类型的常量值。需求通过requires
子句指定,其参数是从常量值,具体类型,形式参数,类型属性和类型函数的应用程序,值和类型的相等性,概念和逻辑连接词构成的表达式 7以下是抽象程序的示例:
template<typename Op> requires(BinaryOperation(Op)) Domain(Op) square(const Domain(Op)& x, Op op) { return op(x, x); }
BinaryOperation的概念在p31上定义。 Domain(Op)
的概念在第12页引入。
requires
的空宏是必要的,因为C ++还没有完全实现它所需的支持。因此,目前,它充当了文档辅助工具,而不是C ++编译器可以采取的行动。但毫无疑问,C ++ 17将更接近能够处理它。
这本书非常有趣,但它也非常紧凑,有时难以理解。
答案 3 :(得分:1)
它是一个奇特的&#39;发表评论的方式。在运行预处理器之后,代码如下所示:
template<typename T>
void construct(T& p)
{
new (&p) T();
}
如果他们写下来,也许会更清楚:
#define requires(this_doesnt_appear_to_the_right_so_the_result_is_nothing)
但这有点啰嗦和迂腐。