c++ - 如何转发声明已在其他地方使用默认值转发声明的模板类型

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

所以 this question 的完美答案声明您可以在前向声明中默认模板类型,但是:

You can specify each default template argument only once

这在链接的问题中得到了更完整的指定,但是 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 。这意味着我必须转发声明。 但是我无法匹配默认的前向声明,因为默认只能声明一次。

如何编写依赖于另一个 header 前向声明中的默认值的前向声明和前向 typedef?

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

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 默认前向声明。

最佳答案

简单的回答是你不能。您要么必须以某种方式保证永远不会包含其他声明,以便您可以指定自己的默认值,要么需要依赖该其他声明。

但我感觉这是一个 XY problem ,对于以下语句:

But I don't want to include Boost in my headers.

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

  • 确保排除使用 ptree 的位使用预处理器指令( #if/#endif block )
  • 使用 C++17 的 __has_include()测试 <boost/property_tree/ptree.hpp> 是否存在,然后包含它(如果存在),或者声明您自己的 ptree如果没有。

关于c++ - 如何转发声明已在其他地方使用默认值转发声明的模板类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48302501/

相关文章:

c++ - sclite (SCTK),C++ 模板参数 Filter::Filter* 无效。 Cygwin

c++ - 使用 class::factory(); 实现 operator<<

c++ - 如何防止手动实例化所有模板类型?

c++ - 如何将 ""本身显示为字符串

c++ - 在成员变量中保存任何类型的 C++ 模板类

r - 使用 'bquote'(或替代方法)从符号构造函数

c++ - 另一个模板循环依赖问题

同一 .NET 应用程序中的 C# 和 C++ 代码?

java - 可访问、跨平台、相关的 UI 框架?

ruby - 可以通过多少种方法将方法添加到 ruby​​ 对象?