我可以解释一下下面代码中的几行吗?

2024-01-22

我想了解以下代码是如何工作的。它基本上可以用于对“调试”C++ 容器进行排序,但我在理解第 3、4、12 和 13 行以及它们的作用时遇到了一些困难。如果我能得到一个简短的解释,那就太好了。谢谢。

template <typename T> class range { public: T begin, end; };
template <typename T> range <T> make_range (const T& b, const T& e) { return range <T> {b, e}; }
template <typename T> auto dec (T* x) -> decltype(std::cerr << *x, 0); // 3
template <typename T> char dec (...);  // 4
class view {
private:
    std::ostream& stream;
public:
     view (std::ostream&);
    ~view ();
#ifdef Z_LOCAL
    template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type operator << (const T&);  // 12
    template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type operator << (const T&);  // 13
    template <typename T> view& operator << (const range <T>&);
    template <typename A, typename B> view& operator << (const std::pair <A, B>&);
#else
    template <typename T> view& operator << (const T&);
#endif
};

view::view (std::ostream& os = std::cerr) : stream (os) { }

view::~view () { stream << std::endl; }

#ifdef Z_LOCAL
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type view::operator << (const T& t)
{ stream << std::boolalpha << t; return *this; }

template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type view::operator << (const T& t)
{ return *this << make_range(begin(t), end(t)); }

template <typename T> view& view::operator << (const range <T>& r)
{ stream << "["; for (auto i = r.begin, j = i; i != r.end; ++i) *this << *i << (++j == r.end ? "]" : ", "); return *this; }

template <typename A, typename B> view& view::operator << (const std::pair <A, B>& p)
{ stream << '(' << p.first << ", " << p.second << ')'; return *this; }
#else
template <typename T> view& view::operator << (const T&)
{ return *this; }
#endif

#define print(x) " [" << #x << ": " << x << "] "
view debug (std::cerr);


以下声明使用了依赖于 SFINAE 的技术(替换失败不是错误):

// #3 : works only if  (std::cerr << *x) works
template <typename T> auto dec (T* x) -> decltype(std::cerr << *x, 0);

// #4 : works for everything, but only if #3 fails
template <typename T> char dec (...); 

考虑某种类型T例如double。然后是下面的代码,其中x is a double*:

std::cerr << *x;

会编译得很好,这意味着这段代码:

decltype(std::cerr << *x, 0);

格式良好,并且评估为int。然后编译器会选择#3 when T是一个可以这样使用的类型。

另一方面,如果T是像一个vector<double>,那么decltype格式不正确(因为您无法流式传输vector to cerr),所以编译器别无选择,只能选择#4.


上面的声明只是简单的帮助器,用于#12 and #13. If T是一种适用于#3, then dec返回类型为int,并且匹配以下重载:

// #12
template <typename T> typename std::enable_if <sizeof dec <T> (0) != 1, view&>::type operator << (const T&);

because sizeof dec <T>不会是1。

If T效劳于#4(因为它不起作用#3), then dec返回类型为int,以及以下过载#13已匹配:

// #13
template <typename T> typename std::enable_if <sizeof dec <T> (0) == 1, view&>::type operator << (const T&); 

because sizeof dec <T>正好是 1(a 的大小char).


请注意,真正的区别在于如何#12 and #13 are defined。如果您看到定义,它们会处理以下情况T是否可以适当地进行流式传输。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我可以解释一下下面代码中的几行吗? 的相关文章

随机推荐

  • 如何使用 powershell 脚本控制窗口的“状态”(最大化、最小化、恢复)?

    我需要能够运行此脚本并使其最大化窗口 如果尚未最大化 如果不是 则恢复窗口 该窗口就是当前活动的窗口 因此无需获取具体信息 但如果您这样做 则可获得奖励积分 8O 我计划通过快捷键激活它 它确实需要在PS v1下运行 我知道 我知道 但我无
  • 无法读取 d3.force 实现中未定义的属性“权重”

    我已经被这个问题困扰了一段时间 甚至根据现有的答案也不知道该怎么做 我在统一响应的最后一个 JSON 条目上不断收到此错误 paperCount 1 PMIDs 20626970 authorA 79 authorB 80 paperCou
  • GraphQL:过滤数组中的数据

    我确信这是一件简单的事情 但我在 GraphQL 的文档或 Graphcool 的文档中找不到任何内容 假设我有一个具有此模式的实体 新的 GraphQL 用户 如果我在模式表示中犯了错误 抱歉 Book name String autho
  • netbeans php插件使用FTP上传文件时如何控制文件权限

    每当 netbeans 执行 ftp 上传时 都会使用设置为 640 的权限上传文件 这会导致 PHP 抛出以下错误 Warning Unknown failed to open stream Permission denied in Un
  • 在不禁用滚动功能的情况下防止 iOS 反弹

    我正在尝试实现一种解决方案 以防止当网页内容大于视口时 iOS 版 Safari 中出现 iOS 反弹效果 我正在处理的页面的结构非常具体 并且与此页面非常相似http new salt ch http new salt ch 基本结构是基
  • 根据文件大小和时间回滚日志

    我一直在尝试建立一个简单的 logback 项目来按日期和文件大小滚动我的日志文件 到目前为止我无法让我的附加程序滚动到另一个文件 相反 它写入由
  • 如何重置Codemirror编辑器?

    我想重置 Codemirror 编辑器的所有内容 理想情况下 这应该清除文本区域 删除所有标记并清除历史记录 实现这一目标的最佳方法是什么 cm setValue cm clearHistory cm clearGutter gutterI
  • 从父类访问属性时未定义的属性

    当类 B 是类 A 的子级并且应该使用 扩展 继承其属性时 我无法弄清楚如何使用类 B 访问类 A 的属性 基本上 我有 class A function construct this gt foo foo class B extends
  • 为什么 sum 的值会变成负数? [复制]

    这个问题在这里已经有答案了 我编写了以下 C 代码来查找给定数组的前 49 个数字的总和 但总和为负数 include
  • 覆盖 Laravel 容器中的 Singleton

    我想知道是否有一种简单的方法来覆盖 Laravel 框架核心中的单例服务集 例如我正在尝试使用以下提供程序重写 app name 命令服务 use Hexavel Console AppNameCommand use Illuminate
  • 如何返回类型列表中最大的类型?

    我将如何创建一个类模板来返回其类型sizeof比其他人都大 例如 typename largest
  • ORA-06530: 对未初始化复合的引用

    当我执行包时 我收到一条错误消息 emp test 中出现错误 ORA 06530 引用未初始化的组合 你能解释一下如何初始化包中的对象类型吗 CREATE OR REPLACE TYPE emp obj AS OBJECT emp no
  • 将一些 C# 通用代码重写为 F#

    我正在尝试重写这样的通用代码 C U Upcast
  • PHP - 使参考参数可选?

    假设我在 PHP 中定义了一个函数 最后一个参数是通过引用传递的 有什么办法可以让它成为可选的吗 我怎么知道它是否已设置 我从未在 PHP 中使用过引用传递 因此下面可能存在一个愚蠢的错误 但这里有一个示例 foo function bar
  • 如何为 C# Windows 服务配置 log4net

    我有一个 Windows 服务 其中 app config 文件和 log4net config 文件是分开的 日志记录不起作用 在我的 app config 文件中 我有以下部分
  • 如何使用mock的@patch来模拟在单独的Python模块中定义的函数

    我正在尝试使用模拟和 patch 装饰器为 Python 应用程序构建测试 给定以下目录结构 mypackage mymodule init py somefile py myothermodule tests init py test f
  • 在 OpenCV 中绘制梯度向量场

    我想计算灰度图像的梯度 平滑平面在代码中 并将其绘制为 OpenCV 中的矢量场 叠加到现有图像上 我尝试应用一对 Sobel 运算符 我也尝试过 Scharr 来计算沿 x 和 y 的两个导数 如 OpenCV 文档中所述 但当我尝试绘图
  • 如何在prolog中使用递归绘制直角三角形?

    我得到这个直角三角形的答案 如下所示 shape shape 0 6 shape S A S lt A count 0 S S1 is S 1 shape S1 A shape S X S gt X count A B A lt B wri
  • 如何测试 SQL Server 触发器中的多行操作?

    我的幼儿园 SQL Server 告诉我 可以使用插入和删除的伪表中的多行来触发触发器 我在编写触发代码时大多考虑到这一点 通常会导致一些基于游标的混乱 现在我真的只能测试它们一次发射一行 如何生成多行触发器以及 SQL Server 实际
  • 我可以解释一下下面代码中的几行吗?

    我想了解以下代码是如何工作的 它基本上可以用于对 调试 C 容器进行排序 但我在理解第 3 4 12 和 13 行以及它们的作用时遇到了一些困难 如果我能得到一个简短的解释 那就太好了 谢谢 template