【问题标题】:std::make_shared not working, but creating the pointer using "new" works finestd::make_shared 不起作用,但使用“new”创建指针工作正常
【发布时间】:2019-09-22 21:02:33
【问题描述】:

我目前正在为我的游戏引擎制作一个 GUI 系统。我尝试使用std::make_shared() 为“GUImovingbar”组件之一创建共享指针,但编译时出现以下错误

'std::shared_ptr<_other> std::make_shared(_Types &&...)': 无法从'initializer list'推导出'_Types &&...'的模板参数

但是,当我使用完全相同的输入创建一个新指针时,它编译得很好,没有错误。这让我觉得有点奇怪。我在这里错过了什么?

使用std::make_shared()的代码:

this->playerhullbar = std::make_shared<GUImovingbar>(
    "right",
    { 50,hully }, //scoords
    globalguitextures[findStringSrdPointerPairVectElement(globalguitextures, "barbackground")].second,
    { 0,static_cast<double>(maxplayerhullint),static_cast<double>(maxplayerhullint) },
    { 50,hully,250, hully,2,100 },//for int vector input ("bsbebdbc"): 1  barxstart, 2  y , 3 barendx, 4 y, 5 distance between bars in px, 6 bar count
    { 0,255,0 },
    bartextvect
    );

以上导致错误:

'std::shared_ptr<_other> std::make_shared(_Types &&...)': 无法从'initializer list'推导出'_Types &&...'的模板参数

以下根本不会导致错误:

std::shared_ptr<GUImovingbar> newptr(new GUImovingbar(
    "right",
    { 50,hully}, //scoords
    globalguitextures[findStringSrdPointerPairVectElement(globalguitextures, "barbackground")].second,
    { 0,static_cast<double>(maxplayerhullint),static_cast<double>(maxplayerhullint) },
    { 50,hully,250, hully,2,100 },//for int vector input ("bsbebdbc"): 1  barxstart, 2  y , 3 barendx, 4 y, 5 distance between bars in px, 6 bar count
    { 0,255,0 },
    bartextvect)
); 
this->playerhullbar = newptr;

【问题讨论】:

  • 我不认为你想要这里的“makefile”标签。这似乎根本与 makefile 无关。
  • GUImovingbar 有定义的构造函数吗? std::make_shared 不适用于聚合初始化 iirc。
  • @Yksisarvinen 是的 GUImovingbar 有一个定义的构造函数

标签: c++ makefile std shared


【解决方案1】:

作为模板函数,std::make_shared 在给定参数的情况下尝试为您的类找到合适的构造函数。由于您给了它初始化列表(括号中的东西),它对这些列表应该初始化什么类型感到困惑,因此找不到合适的构造函数。然而,当你正确使用构造函数时,歧义就被消除了,因为由于参数的位置,编译器知道列表应该初始化什么类型,并相应地转换它们。

如果您仍想使用std::make_shared,则必须通过将初始化列表的类型放在列表之前来消除它们的歧义:

this->playerhullbar = std::make_shared<GUImovingbar>(
    "right",
    Scoords { 50,hully },
    globalguitextures[findStringSrdPointerPairVectElement(globalguitextures, "barbackground")].second,
    Rect { 0,static_cast<double>(maxplayerhullint),static_cast<double>(maxplayerhullint) },
    std:vector<int> { 50,hully,250, hully,2,100 },
    Color { 0,255,0 },
    bartextvect
);

(或者,如果你有一个旧的编译器,也可以使用前一种带括号的语法:std:vector&lt;int&gt;({ 50,hully,250, hully,2,100 })

【讨论】:

    【解决方案2】:

    问题在于您在 make_shared 调用中进行的聚合初始化。如果您使用new GUImovingbar(...) 创建一个对象,您将直接调用构造函数,因此编译器确切地知道哪个参数属于哪个类型。这使您能够聚合初始化所述参数。

    但是,如果您调用make_shared,则所有参数都必须从您传递给函数的值中推导出来(因为它是一个模板)。这基本上是这样的:

    auto x = {10, "hello", 4};
    

    编译器应该如何知道这实际上是什么类型?

    如果您仍想使用make_shared,您必须使用它们的名称显式初始化类型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 2021-12-24
      相关资源
      最近更新 更多