【问题标题】:How do I forward declare a template type that has been forward declared elsewhere with a defaulting如何转发声明已在其他地方转发声明的模板类型具有默认值
【发布时间】:2018-01-17 13:38:29
【问题描述】:

因此,this question 的出色回答表明您可以在前向声明中默认模板类型,但是:

每个默认模板参数只能指定一次

这在链接的问题中有更完整的说明,但 Boost 的属性树内容适用于 ptree 类型:

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

但是basic_ptree 类是这样定义的:

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

ptree typedef 仅使用 2 个模板参数定义的唯一原因是,在它的 typedef 之前有前向声明:

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

这让我想到了我的实际问题。我需要传递一个ptree。但我不想在我的标题中包含Boost。这意味着我必须转发声明。 但是我无法匹配默认的前向声明,因为默认只能声明一次。

如何编写依赖于另一个标头前向声明中的默认设置的前向声明和前向 typedef?

我目前正在这样做,但这意味着我转发typedef'ing,我正在制作一个typedef: p>

template <class Key, class Data, class KeyCompare> class basic_ptree;
typedef basic_ptree<std::string, std::string, std::less<std::string>> ptree; 

为了保持一致性,我想依赖与原始 ptree typedef 所依赖的 basic_ptree 相同的默认前向声明。

【问题讨论】:

  • 我目前正在这样做,但这意味着我不是前向类型定义,我正在制作一个 new 类型定义:template &lt;class Key, class Data, class KeyCompare&gt; class basic_ptree; typedef basic_ptree&lt;std::string, std::string, std::less&lt;std::string&gt;&gt; ptree; 我不想由于担心不一致,请制作我自己的 typedef。
  • 啊,为什么要在狭窄的评论空间中添加您当前的方法?
  • @StoryTeller 我认为问题已经太多了。它变得势不可挡。你不这么认为吗?
  • 就我个人而言,我宁愿再看到 10 条线段 (---),而不是从 cmets 解析代码(这对我个人来说是一种呻吟)。
  • 只包含“ptree_fwd.hpp”标头真的很糟糕吗?

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


【解决方案1】:

简短的回答是你不能。您要么必须以某种方式保证永远不会包含另一个声明,以便您可以指定自己的默认值,或者您需要依赖于另一个声明。

但我感觉这是XY problem,用于以下声明:

但我不想在标题中包含 Boost。

为什么不呢?您的代码显然依赖于 Boost 的 ptree,因此任何使用您的代码的人都必须安装 Boost。如果您希望在未安装 Boost 时也编译您的声明,有几种选择:

  • 确保使用预处理器指令排除使用ptree 的位(#if/#endif 块)
  • 使用 C++17 的 __has_include() 来测试 &lt;boost/property_tree/ptree.hpp&gt; 是否存在,如果存在则包含它,如果不存在则声明您自己的 ptree

【讨论】:

  • ptree 的使用在我的实现层标头内部。重要的是我的接口层不要拉入 Boost。
猜你喜欢
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
相关资源
最近更新 更多