Set*_*son 18 c++ templates forward-declaration
是否可以转发声明一个使用默认参数的类而不指定或知道这些参数?
例如,我想boost::ptr_list< TYPE >在Traits类中声明一个,而不将整个Boost库拖动到包含特征的每个文件中.我想声明
namespace boost { template<class T> class ptr_list< T >; },但这不起作用,因为它与真正的类声明不完全匹配:
template < class T,
class CloneAllocator = heap_clone_allocator,
class Allocator = std::allocator<void*>
>
class ptr_list { ... };
Run Code Online (Sandbox Code Playgroud)
我的选择只是与它一起生活或boost::ptr_list< TYPE, boost::heap_clone_allocator, std::allocator<void*>在我的特质课程中指定吗?(如果我使用后者,我想也必须转发声明boost::heap_clone_allocator和包含<memory>,我想.)
我查看了Stroustrup的书,SO和其他互联网,但没有找到解决方案.通常人们担心不包括STL,解决方案是"只包括STL标题".但是,Boost是一个更大规模和编译器密集型的库,因此除非我绝对必须,否则我更愿意将其删除.
Pot*_*ter 14
是.可以随时随地指定默认模板参数,只要声明不会相互冲突即可.它们最终从各种声明合并在一起.
即使这是合法的:
template< class A, class B, class C = long >
class X;
template< class A, class B = int, class C >
class X;
template< class A = short, class B, class C >
class X { };
Run Code Online (Sandbox Code Playgroud)
§14.1/ 10中给出了类似的例子.根据该段,函数默认参数的行为类似.
祝你的前瞻声明能够表现自己,而不是对所有事情都有好处!
我不认为你可以使用默认参数转发声明模板,除非有问题的库提供了自己的前向声明头.这是因为您无法重新指定默认参数(即使它们匹配... gcc仍会报告"错误:重新定义默认参数").
所以据我所知,解决方案是库提供前向声明头Foo_fwd.h:
#ifndef INCLUDED_Foo_fwd_h_
#define INCLUDED_Foo_fwd_h_
template<class T, class U=char> class Foo; // default U=char up here
#endif
Run Code Online (Sandbox Code Playgroud)
然后在Foo.h中的完整实现将是:
#ifndef INCLUDED_Foo_h_
#define INCLUDED_Foo_h_
#include "Foo_fwd.h"
template<class T, class U> class Foo { /*...*/ }; // note no U=char here
#endif
Run Code Online (Sandbox Code Playgroud)
所以现在你的代码也可以使用Foo_fwd.h ......但遗憾的是,由于这种方法需要修改原始的Foo.h以删除默认参数,因此不会扩展到第三方库.也许我们应该游说C++ 0x工作人员允许等效重新指定默认模板参数,àlatypedef ...?
任何使用您的设施的前向声明 boost 内容的编译单元都需要包含 boost 标头,除非您有某些程序实际上不会使用设施的 boost 部分。
确实,通过前向声明,您可以避免包含此类程序的 boost 标头。#ifdef但是对于那些实际使用 boost 部分的程序,您必须手动包含 boost 标头(或有一个)。
请记住,未来的 Boost 版本中可能会添加更多默认模板参数。我建议不要走这条路线。如果您的目标是加快编译时间,我会考虑使用 a#define来指示是否应禁用使用该 boost 库的代码。这样您就可以避免前向声明的麻烦。
| 归档时间: |
|
| 查看次数: |
9246 次 |
| 最近记录: |