基于智能指针的 CRTP 习惯用法的编译问题

2024-01-10

我正在尝试为 CRTP 示例编译一个最小的工作示例这篇博文 https://www.fluentcpp.com/2017/09/12/how-to-return-a-smart-pointer-and-use-covariance/,它基于智能指针。

根据代码示例,我编写了两个文件:标头和源代码。

Header (crtp.h):

#include <memory>

class Cloneable
{
 public:
  virtual ~Cloneable() {}

  std::shared_ptr<Cloneable> clone() const
  {
    return std::shared_ptr<Cloneable>(this->clone_raw());
  }

 private:
  virtual Cloneable* clone_raw() const = 0;
};

template <typename Derived, typename Base>
class CloneInherit<Derived, Base>: public Base
{
 public:
  std::shared_ptr<Derived> clone() const
  {
    return std::shared_ptr<Derived>(static_cast<Derived*>(this->clone_raw()));
  }

 private:
  virtual CloneInherit* clone_raw() const override
  {
    return new Derived(*this);
  }
};

class Concrete: public CloneInherit<Concrete, Cloneable> {};

Source (example.cc):

#include <memory>

#include "crtp.h"

int main()
{
  std::shared_ptr<Concrete> c = std::make_shared<Concrete>();
  std::shared_ptr<Concrete> cc = c->clone();
  Cloneable* p = c.get();
  std::shared_ptr<Cloneable> pp = p->clone();
  return 0;
}

此代码编译失败并出现以下错误:

In file included from example.cc:3:
./crtp.h:18:7: error: explicit specialization of non-template class 'CloneInherit'
class CloneInherit<Derived, Base>: public Base
      ^           ~~~~~~~~~~~~~~~
./crtp.h:29:16: error: no matching constructor for initialization of 'Concrete'
    return new Derived(*this);
               ^       ~~~~~
./crtp.h:33:7: note: in instantiation of member function 'CloneInherit<Concrete, Cloneable>::clone_raw' requested here
class Concrete: public CloneInherit<Concrete, Cloneable>
      ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4411:26: note: in instantiation of member function 'std::__1::__shared_ptr_emplace<Concrete, std::__1::allocator<Concrete> >::__shared_ptr_emplace' requested
      here
    ::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
                         ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4775:29: note: in instantiation of function template specialization 'std::__1::shared_ptr<Concrete>::make_shared<>' requested here
    return shared_ptr<_Tp>::make_shared(_VSTD::forward<_Args>(__args)...);
                            ^
example.cc:7:42: note: in instantiation of function template specialization 'std::__1::make_shared<Concrete>' requested here
      std::shared_ptr<Concrete> c = std::make_shared<Concrete>();
                                         ^
./crtp.h:33:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const CloneInherit<Concrete, Cloneable>' to 'const Concrete' for 1st argument
class Concrete: public CloneInherit<Concrete, Cloneable>
      ^
./crtp.h:33:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'const CloneInherit<Concrete, Cloneable>' to 'Concrete' for 1st argument
class Concrete: public CloneInherit<Concrete, Cloneable>
      ^
./crtp.h:33:7: note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided
2 errors generated.

我可以通过一些方法来修复这些错误。我可以删除<Derived, Base>声明中的专业化CloneInherit使第一个错误消失并更改定义clone_raw()的函数CloneInherit to

virtual CloneInherit* clone_raw() const override
{
  return new CloneInherit(*this);
}

但我不确定这是否会得到与帖子最初意图相同的结果。


他的帖子确实有几个错别字:

固定版本:

#include <memory>

class cloneable
{
public:
   virtual ~cloneable() {}

   std::unique_ptr<cloneable> clone() const
   {
      return std::unique_ptr<cloneable>(this->clone_impl());
   }

private:
   virtual cloneable * clone_impl() const = 0;
};

template <typename Derived, typename Base>
class clone_inherit : public Base
{
public:
   std::unique_ptr<Derived> clone() const
   {
      return std::unique_ptr<Derived>(static_cast<Derived*>(this->clone_impl()));
   }

private:
   clone_inherit* clone_impl() const override
   {
      return new Derived(*static_cast<const Derived*>(this));
   }
};

class concrete : public clone_inherit<concrete, cloneable>
{
};

int main()
{
   std::unique_ptr<concrete> c = std::make_unique<concrete>();
   std::unique_ptr<concrete> cc = c->clone();

   cloneable * p = c.get();
   std::unique_ptr<cloneable> pp = p->clone();
}

Demo http://coliru.stacked-crooked.com/a/64c62b9bb00aaedd

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

基于智能指针的 CRTP 习惯用法的编译问题 的相关文章

  • 与 for_each 或 std::transform 一起使用时,如何调用 C++ 函子构造函数

    我以前从未使用过 C 函子 所以我只是想了解它们是如何工作的 例如假设我们有这个函子类 class MultiplyBy private int factor public MultiplyBy int x factor x int ope
  • C#.Net 邮件将进入垃圾邮件文件夹

    我正在从 ASP net Web 应用程序发送电子邮件 邮件发送成功 没有失败 但大多数都进入了垃圾邮件文件夹 请帮助我克服垃圾邮件过滤器 我的发送邮件代码 public void SendMail string FromAddress s
  • 捕获 .aspx 和 .ascx 页面中的异常

    问题说明了一切 请看以下示例代码 ul li li ul
  • 关于逻辑/算法的想法以及如何防止线程写入 Sql Server 中的竞争

    我有以下逻辑 public void InQueueTable DataTable Table int incomingRows Table Rows Count if incomingRows gt RowsThreshold async
  • EntityHydrate 任务失败

    我最近安装了 Visual Studio 11 Beta 和 Visual Studio 2010 之后 我无法在 Visual Studio 2010 中构建依赖于 PostSharp 的项目 因此我卸载了 Visual Studio 1
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • 2个对象,完全相同(除了命名空间)c#

    我正在使用第三方的一组网络服务 但遇到了一个小障碍 在我手动创建将每个属性从源复制到目标的方法之前 我想我应该在这里寻求更好的解决方案 我有 2 个对象 一个是 Customer CustomerParty 类型 另一个是 Appointm
  • 混合模型优先和代码优先

    我们使用模型优先方法创建了一个 Web 应用程序 一名新开发人员进入该项目 并使用代码优先方法 使用数据库文件 创建了一个新的自定义模型 这 这是代码第一个数据库上下文 namespace WVITDB DAL public class D
  • Android NDK 代码中的 SIGILL

    我在市场上有一个 NDK 应用程序 并获得了有关以下内容的本机崩溃报告 SIGILL信号 我使用 Google Breakpad 生成本机崩溃报告 以下是详细信息 我的应用程序是为armeabi v7a with霓虹灯支持 它在 NVIDI
  • Makefile 和 .Mak 文件 + CodeBlocks 和 VStudio

    我对整个 makefile 概念有点陌生 所以我对此有一些疑问 我正在 Linux 中使用 CodeBlocks 创建一个项目 我使用一个名为 cbp2mak 的工具从 CodeBlocks 项目创建一个 make 文件 如果有人知道更好的
  • OpenGL:如何检查用户是否支持glGenBuffers()?

    我检查了文档 它说 OpenGL 版本必须至少为 1 5 才能制作glGenBuffers 工作 用户使用的是1 5版本但是函数调用会导致崩溃 这是文档中的错误 还是用户的驱动程序问题 我正在用这个glGenBuffers 对于VBO 我如
  • Libev,如何将参数传递给相关回调

    我陷入了 libev 中争论的境地 通常 libev 在类似的函数中接收包 接收回调 没关系 但是实际操作中 我们需要派遣一个亲戚 写回调 根据收到的包裹处理具体工作 例如 S RECV MSG pstRecvMsg S RECV MSG
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • wordexp 失败时我们需要调用 wordfree 吗?

    wordexp 失败时我们需要调用 wordfree 吗 在某些情况下 调用 wordfree 似乎会出现段错误 例如 当 wordfree 返回字符串为 foo bar 的错误代码时 这在手册页中并不清楚 我已经看到在某些错误情况下使用了
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 在哪里可以找到 Microsoft.Build.Utilities.v3.5

    如何获取 Microsoft Build Utilities v3 5 我正在使用 StyleCop 4 7 Stylecop dll 中的 StyleCop msbuild 任务似乎依赖于 Microsoft Build Utilitie
  • C++ 指针引用混淆

    struct leaf int data leaf l leaf r struct leaf p void tree findparent int n int found leaf parent 这是 BST 的一段代码 我想问一下 为什么
  • 如何高效计算连续数的数字积?

    我正在尝试计算数字序列中每个数字的数字乘积 例如 21 22 23 98 99 将会 2 4 6 72 81 为了降低复杂性 我只会考虑 连续的数字 http simple wikipedia org wiki Consecutive in
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何在 C# 中获取 CMD/控制台编码

    我需要指定正确的代码页来使用 zip 库打包文件 正如我所见 我需要指定控制台编码 在我的例子中为 866 C Users User gt mode Status for device CON Lines 300 Columns 130 K

随机推荐

  • Firebase JavaScript SDK - 检索用户 IP 地址

    假设我的浏览器脚本自动匿名登录任何用户 是否可以收集用户的公共 IP 地址 我找到了firebase auth currentUser metadata财产 但它只包括LastSignInTime and creationTime 用户公共
  • 如何在 codemirror 编辑器中使用 cypress .type() 进行输入?

    我正在写一些cypress测试 Codemirror 编辑器 我有用cypress在输入字段中键入 我正在努力实现cy type 在 CodeMirror 编辑器中 我在 codemirror 中的数据位于范围内 pre class Cod
  • Kivy Spinner:从 Spinner 中选择一个值时触发的任何事件

    我介绍一个Spinner在我的小部件中 每次我从中选择不同的值时 我都想执行一些操作 是否可以 我似乎只收到事件on press and on release 但是当选择不同的值时它们不会被触发 此致 Bojan 因为每次 attr val
  • 如何区分我自己的类和 gem 的类

    我有一个 Rails 项目 我已经研究了一段时间了 像许多 Rails 项目一样 我有一个 User 类 在我的一个控制器中 我需要从我正在使用的 gem 访问一些方法 gem 中的示例代码演示了如何使用包含到特定 gem 模块 我不会在这
  • PGAdmin - 为什么数据库限制(和高级属性)被禁用?

    我希望限制在浏览器树 层次结构中看到的数据库数量 因为它是一个拥有数百个数据库的 AWS 服务器 基于这个答案 https stackoverflow com questions 12663639 how to hide databases
  • 春季时间表 - 每月最后一天不工作

    我想在 每月最后一天 10 15 和 每月第一个星期日 运行春季调度程序作业 我在下面尝试过 但在初始化 spring 上下文时出现错误 org springframework boot SpringApplication 应用程序启动失败
  • Excel:SUMPRODUCT 计算共享工作负载(以小时为单位)和百分比

    我要再问一个问题 Excel 带百分比的 SUMPRODUCT https stackoverflow com questions 71080332 excel sumproduct with percentages 没有以另一种方式解决
  • 如何修复curl 56 GnuTLS接收错误(-110):TLS连接未正确终止[重复]

    这个问题在这里已经有答案了 同样的问题 git 错误 RPC 失败 curl 56 GnuTLS 接收错误 110 https stackoverflow com questions 50813406 and 错误 RPC 失败 curl
  • Github 页面上的 Angular 4 应用程序

    我有一个简单的Angular 4 我想要托管的应用程序Github Pages 执行此操作的选项来自Angular CLI似乎已删除 有没有办法做到这一点 如果有的话怎么办 这是我的 package json name e portfoli
  • Javascript 抓取 document.URL 的最后一部分? [复制]

    这个问题在这里已经有答案了 我试图获取当前网址的最后一部分 URL http example com test action http example com test action 我正在努力抓住 行动 URL 在该结构中始终保持一致 但
  • 将值从 HTML 传递到 CSS

    我感兴趣是否可以将值从 html 传递给 css 类 像这样 例子 div class Some text div style mt mpx margin top mpx px 我听说这种方式在 Less 中是可能的 不 你想要的方式在 C
  • ConnectivityManager 在获取网络信息时崩溃

    我是 Android 新手 当我给出以下代码片段时 我的 Android 应用程序崩溃了 ConnectivityManager manager ConnectivityManager this getSystemService Conte
  • 如何在 Nexmo 中向美国号码发送文本

    向菲律宾发送信息非常简单 但在美国的数字中 我必须进行验证 但我不知道如何进行 我开始了2F认证 但似乎我不知道下一步该怎么做 我的问题 如何在 Nexmo 中添加发送文本到美国号码 对于美国 您必须从您的 nexmo 帐户创建一个短代码
  • 来自本地 json 变量的 d3 饼图

    我正在尝试使用我见过的局部变量 而不是外部文件 中的 json 创建一个圆环图这个帖子 https stackoverflow com questions 10934853 d3 js loading json without a http
  • 由于格式不正确,加载程序集失败

    我开发了一个相当大的 Windows Forms net C 应用程序 其中包含多个程序集 最初 每个程序集都是为目标平台 任何 CPU 构建的 由于 x64 机器上的 Crystal Reports 存在问题 我们必须为 x86 目标平台
  • 如何在react-quill中注册对齐样式

    我在用着反应鹅毛笔 https www npmjs com package react quillnpm 包并在 nextjs 中动态导入它 我还使用 create next app 样板 我能够让反应鹅毛笔编辑器工作 但是 我无法获取使用
  • 地理编码器 Gem 无法在生产环境中工作

    所以我正在使用Geocoder https github com alexreisner geocoder根据用户提交表单时提供的地址提取纬度和经度坐标 我这样做是为了使用 Google 地图 API 绘制标记 这在开发中非常有效 零问题
  • .NET 4.5 中是否已弃用 ObjectContext?

    我一直在使用ObjectContexts已经很长一段时间了 现在我已经安装了 VS 2012 令我惊讶的是 实体数据模型没有创建代码生成项的选项ObjectContexts and EntityObjects代替DbContexts and
  • Mongoose 在 Node.js 中创建多租户支持连接

    我正在研究一种使用 node js mongoose 和 mongodb 实现多数据库以支持多租户的好方法 我发现 mongoose 支持一种名为createConnection 我想知道使用它的最佳实践 实际上 我将所有这些连接存储在一个
  • 基于智能指针的 CRTP 习惯用法的编译问题

    我正在尝试为 CRTP 示例编译一个最小的工作示例这篇博文 https www fluentcpp com 2017 09 12 how to return a smart pointer and use covariance 它基于智能指