关于C++ 0x标准化过程的最新Herb Sutter旅行报告表明委员会决定完全放弃模板的"导出"概念,并弃用异常规范.
我认为这些都是很好的举动,但我感兴趣的是,如果有人在这里有代码库,这些变化将导致他们不眠之夜吗?
在一个大型项目中,我们有很多类(数千个),并且对于每个类,使用typedef定义了一个特殊的智能指针类型.此智能指针类型是模板类.当我用"gcc -Q"编译时,我发现花了很多时间为每个类编译这些智能指针.这就是我看到smartptr<class1>::methods, then smartptr<class2>::methods... smartptr<class2000>::methods在gcc处理它们时在屏幕上滚动.
有加速这个过程的技巧吗?从smartptr的角度来看,这些类都是相同的,没有enable_if技巧等.
我现在正在尝试的事情:
但以上所有都不是一个完整的解决方案.我想知道是否有另一种方法可以优化编译时间,这是一个让gcc知道的技巧,例如,一旦它在看到其他特化时反复应用相同的知识就解析了smartptr,因为生成代码是相同的.
是的,我知道这是不是很一样,当然......但是,这只是一个疯狂的想法.
或者也许还有其他我不知道的技巧,可以加快编译速度.(只是为了说明我正在谈论的内容,我们可以通过消除其静态成员数据实例来优化另一个模板,这大大减少了编译时间.这根本不明显.)
我刚刚阅读了有关CRTP的wiki文章,我对模板实例化有点困惑.
根据维基,
成员函数体(定义)直到它们的声明后很久才被实例化.
我不太明白这意味着什么.
假设我有一个类模板:
template <typename T>
class A
{
public:
void foo(T t)
{
//...
};
};
Run Code Online (Sandbox Code Playgroud)
当我实例化类模板A时,它是否实例化成员函数foo()?
例如:
//in .cpp file
int main()
{
A<int> a; //question 1
//class template is instantiated here, isn't it?
//What about foo(), is it instantiated too?
a.foo(10); //question 2
//according to the quotation, foo() will not be instantiated until it is used.
//if so, foo() is instantiated right here, not in question 1, right?
}
Run Code Online (Sandbox Code Playgroud) 假设您有以下(格式错误的)程序:
struct A
{
A(int, int)
{
}
};
template <typename T>
class B
{
B()
{
if (sizeof (T) == 1)
{
throw A(0); // wrong, A() needs two arguments
}
}
};
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC编译这个程序没有任何错误,clang ++拒绝它错误.
在我之前的问题中,我问过递归显式模板实例化是否可能.我看到它确实可能; 但是,此实例化仅在本地有效,递归实例化模板的符号不会导出到目标文件,因此不会出现在(共享)库中.所以我在这里更准确地提出问题,就像我之前的帖子一样:
给出一个类似的模板
template<int dim> class Point { ... };
Run Code Online (Sandbox Code Playgroud)
这个模板可以明确地实例化
template class Point<0>;
template class Point<1>;
template class Point<2>;
template class Point<3>;
Run Code Online (Sandbox Code Playgroud)
它将Point<0>...... 的符号导出Point<3>到当前翻译单元的目标文件中.我没有像上面那样单独实例化每个模板,而是想通过一次调用递归地实例化它们.
任何实现这一目标的解决方案都很好,无论是模板元编程的风格,还是通过辅助类
template class RecursiveInstantiate<Point, 3>;
Run Code Online (Sandbox Code Playgroud)
或通过预处理器.在这里,我研究了boost预处理器库,它似乎有一些循环结构.但是,我从未使用过boost预处理器库(任何建议都很受欢迎),但乍一看,如果循环可以与显式模板实例一起使用,我会持怀疑态度.
任何建议,也解释为什么我想要达到的目标是不可能的.
其实我感兴趣的概括这对于喜欢多个模板参数类Node<int i1,int i2,int i3>为I1,I2,I3的所有组合{0,1,2,3}.但我希望能够自己解决这第二部分.像往常一样,我想通过仅在一个转换单元中定义模板来使用显式实例化来加速编译时间,因此我需要将模板的方法导出到目标文件中.
我希望有一个独立于编译器的解决方案,但如果这不可能,我需要用于带有g ++/clang的Linux.
请参阅下文,了解我所获得的解决方案以及我从中获得的最终解决方案.