我可以在前向声明中默认模板参数吗
Am I Allowed to Default a Template Argument in a Forward Declaration
所以我试图了解 Boost 的 ptree
实现发生了什么。
在ptree.hpp中basic_ptree
实际定义为:
template<class Key, class Data, class KeyCompare>
class basic_ptree
在 ptree_fwd.hpp 中有一个看起来像 basic_ptree
的前向声明但是有一个新的模板参数 default:
template < class Key, class Data, class KeyCompare = std::less<Key> >
class basic_ptree;
最后在 ptree_fwd.hpp ptree
是 typedef
'd:
typedef basic_ptree<std::string, std::string> ptree;
这是 ptree_fwd.hpp 中的前向声明,对吧?所以我可以在前向声明中默认模板参数?
是的,你可以。但是每个默认模板参数只能指定一次。
The set of default template-arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are (dcl.fct.default).
[ Example:
template<class T1, class T2 = int> class A;
template<class T1 = int, class T2> class A;
is equivalent to
template<class T1 = int, class T2 = int> class A;
— end example ]
A template-parameter shall not be given default arguments by two different declarations in the same scope. [ Example:
template<class T = int> class X;
template<class T = int> class X { /* ... */ }; // error
— end example ]
(注意,这些是从最新的草案中摘录的,但据我所知,这些规则近年来没有改变)
如果您希望在仅知道声明时能够使用默认参数,则必须在声明中定义它们。以上也回答了您在评论中提出的问题:
I feel like this gets really nasty really quick. What if I include 2 separate headers that include different defaults in their forward declarations? Or is that what you're addressing?
如果您这样做,您的程序将是 ill-formed,因为您只能指定每个默认参数一次。有两个声明,一个定义默认参数,另一个不定义,并不会真正造成任何问题,因为它们彼此并不存在分歧。这仅意味着如果仅知道没有默认值的版本,则在实例化模板时必须指定 all 个参数。
我个人的意见是在 header 中只有一个声明指定默认模板参数,然后在需要声明的地方包含 header(以及定义).
所以我试图了解 Boost 的 ptree
实现发生了什么。
在ptree.hpp中basic_ptree
实际定义为:
template<class Key, class Data, class KeyCompare>
class basic_ptree
在 ptree_fwd.hpp 中有一个看起来像 basic_ptree
的前向声明但是有一个新的模板参数 default:
template < class Key, class Data, class KeyCompare = std::less<Key> >
class basic_ptree;
最后在 ptree_fwd.hpp ptree
是 typedef
'd:
typedef basic_ptree<std::string, std::string> ptree;
这是 ptree_fwd.hpp 中的前向声明,对吧?所以我可以在前向声明中默认模板参数?
是的,你可以。但是每个默认模板参数只能指定一次。
The set of default template-arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are (dcl.fct.default).
[ Example:
template<class T1, class T2 = int> class A; template<class T1 = int, class T2> class A;
is equivalent to
template<class T1 = int, class T2 = int> class A;
— end example ]
A template-parameter shall not be given default arguments by two different declarations in the same scope. [ Example:
template<class T = int> class X; template<class T = int> class X { /* ... */ }; // error
— end example ]
(注意,这些是从最新的草案中摘录的,但据我所知,这些规则近年来没有改变)
如果您希望在仅知道声明时能够使用默认参数,则必须在声明中定义它们。以上也回答了您在评论中提出的问题:
I feel like this gets really nasty really quick. What if I include 2 separate headers that include different defaults in their forward declarations? Or is that what you're addressing?
如果您这样做,您的程序将是 ill-formed,因为您只能指定每个默认参数一次。有两个声明,一个定义默认参数,另一个不定义,并不会真正造成任何问题,因为它们彼此并不存在分歧。这仅意味着如果仅知道没有默认值的版本,则在实例化模板时必须指定 all 个参数。
我个人的意见是在 header 中只有一个声明指定默认模板参数,然后在需要声明的地方包含 header(以及定义).