C++模板机制只是一个类型构建器函数吗
Is C++ template mechanism is just a type builder function?
我刚开始思考这个问题。每个C++模板都可以用一个返回类(或函数)对象的"正常"函数来替换?正常表示编译时程序。
因此,我想用"正常函数(指在编译器解析树或类似工具上工作的编译时程序)"来代替C++编译中的模板实例化,并且我不想使用decorative语法。
你认为用下面的想法我们可以取代C++中的整个模板机制吗?你认为这种方式会使模板更容易理解吗?我知道这个问题有点理论化,但我不知道在哪里讨论这个问题的最佳地点。
template<typename T>
struct A
{
int foo();
bool bar;
T data;
};
#if 0
class A(typename T) // class bulder after "("
{
class ret; // class object can only declared in class builder
ret.name = "whatever_compile_time_string";
ret += body // body is a class builder member with class declaration syntax
{
body(); // constructor
~body(); // destructor
int foo(); // method
bool bar; // member
};
ret += member(T, "data"); // "inject" a templated member
return ret;
}
#endif
int main()
{
A<int> a;
#if 0
// create a new class
typedef new class A(int) AInt;
// or
typedef new class A(int); // in this case class.name must be an initialized thing
#endif
}
是。你所描述的是一个宏观系统。C预处理器提供了一种弱形式的宏,但在一般情况下,宏无非是在编译时执行的编写源代码(将源代码作为输入)的程序。
现在,宏理论变得有些复杂。显然,您可以使用任何允许您在编译时执行代码的宏系统来做任何您想做的事情,但为了让做正确的事情变得容易,我们已经做了很多工作。(特别是,有一个可以插入的语法引号结构真的很有帮助。)
有了强大的宏系统,许多以前内置在该语言中的语句可以由用户定义,也可以包含在标准库中。
如果你对这个主题感兴趣,可以看看Scheme,尤其是Racket编程语言。Racket的核心非常小,用户体验的几乎所有语言都是由宏构建的。
否。模板的一个主要特点是它们提供了静态推断的类型安全多态性。
根据定义,你不能在运行时这样做。如果你想把所有东西都转移到运行时,不要使用C++,而是使用为后期绑定优化的东西。
更新:如果你说的是一个在编译时运行的函数,那么(a)你需要你的编译器来解释C++(如果你想用C++编写它),你就失去了声明性函数语言模板的好处。我看不出有什么好处。
C程序员有两种方法可以实现类似C++中模板的效果。然而,我认为使用这些方法代替C++中的模板没有任何好处。但如果你认为模板很难理解,那么看看这些:
通过使用宏:
// N: typename, T: used type
#define MAKE_A(N, T) class N {
public: N(){} ~N(){} bool flag; T data; }
MAKE_A(AInt, int);
MAKE_A(AFloat, float);
通过使用额外的实现头文件:
文件:A.h(不要放置包含保护):
// A_NAME: typename, A_TYPE: used type
class A_NAME {
public:
A_NAME(){}
~A_NAME(){}
bool flag;
A_TYPE data;
};
用法:
#define A_NAME AInt
#define A_TYPE int
#include "A.h"
#undef A_NAME
#undef A_TYPE
#define A_NAME AFloat
#define A_TYPE float
#include "A.h"
#undef A_NAME
#undef A_TYPE
BOOST.PP相对于模板的一个优点是BOOST.PP比使用模板的等效程序编译得更快至少根据boost-devel列表的这篇文章。
即使使用哈希而不是线性来提高gcc的速度查找,我相信使用BOOST.PP仍然更快,我想是因为Walter Bright在参考文章中提到的限制。
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 构造函数正在调用一个使用当前类类型的函数
- 引用一个已擦除类型(void*)的指针
- 在一个模板函数中,若输入的类型是enum类,我该如何使用std::underlying_type
- visual是否可以在c++中创建一个接收无限数量相同类型(或至少相当数量)参数的函数
- 在c++中为double类型的数组创建一个unique_ptr
- 当基类是依赖类型时,这是一个缺陷吗
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 给定一个C++嵌套的私有结构类型,是否有从文件范围静态函数访问它的策略
- C++将一个指针分配给另一个指针时执行的类型检查
- 模板函数如何处理可能共享一个交集的多个类型名称?
- 是否可以在C++中有一个"generic"模板参数,该参数可以是非类型模板参数或类型?
- 取消引用结束指针到数组类型的一个
- 为什么转换函数声明不需要至少一个定义类型说明符
- 如何包装一个函数以适应另一个函数的所需类型
- 使用C++生成泛型类型-一个具有共享实现的模板