我是否允许在前瞻声明中默认模板参数

时间:2018-01-16 13:50:56

标签: c++ templates metaprogramming forward-declaration default-arguments

所以我试图了解Boost的ptree实施情况。

在ptree.hpp basic_ptree中实际定义了:

template<class Key, class Data, class KeyCompare>
class basic_ptree

在ptree_fwd.hpp中,看起来像是basic_ptree的前向声明,但默认使用新的模板参数:

template < class Key, class Data, class KeyCompare = std::less<Key> >
class basic_ptree;

最后在ptree_fwd.hpp ptreetypedef'd:

typedef basic_ptree<std::string, std::string> ptree;

这是ptree_fwd.hpp中的前向声明,对吗?所以我被允许在前向声明中默认模板参数?

1 个答案:

答案 0 :(得分:2)

是的,你可以。但是您只能指定一次默认模板参数。

17.1/14

  

可以使用的默认模板参数集是通过合并模板的所有先前声明中的默认参数获得的,其方式与默认函数参数(dcl.fct.default)相同。

     

[实施例:

template<class T1, class T2 = int> class A;
template<class T1 = int, class T2> class A;
     

相当于

template<class T1 = int, class T2 = int> class A;
     

- 结束示例]

17.1/16

  

模板参数不应由同一范围内的两个不同声明给出默认参数。 [实施例:

template<class T = int> class X;
template<class T = int> class X { /* ... */ };  // error
     

- 结束示例]

请注意,这些摘自最新草案,但近年来这些规则并未因我的知识而改变

如果您希望只知道声明时能够使用默认参数,则必须在声明中定义它们。上面还回答了你在评论中提出的问题:

  

我觉得这真的非常讨厌。如果我在其前向声明中包含2个包含不同默认值的单独标题,该怎么办?或者你正在解决的问题是什么?

如果您这样做,您的程序将是格式错误的,因为您只能指定每个默认参数一次。有两个声明,其中一个定义默认参数而另一个不定义,实际上不会引起任何问题,因为它们彼此之间没有分歧。它只表示如果只知道没有默认值的版本,则在实例化模板时必须指定所有参数。

我个人的意见是在标题中只有一个声明指定默认模板参数,然后在需要声明的地方包含该标题(以及定义)。