从临时

问题描述

我正在使用具有(仅)构造函数的第三方类,如下所示:

class foo  // cannot be altered
{
  public:
    explicit foo(std::istream&);
  ...
};

及其文档建议采取以下方法

std::ifstream from("file.txt");
foo obj(from);
from.close();

我无法更改foo并想用作其他课程的成员

class bar
{
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : obj(std::ifstream(filename))   // error: no matching constructor
   {}
   ...
};

除外,因为它不起作用,因为不能保证从std::ifstream创建的临时filename的生存时间足以构建foo obj,因此不能转换为{{ 1}}(如果std::istream&接受了foo::foo(),情况将有所不同)。

所以我的问题是:我可以使const std::istream&的构造函数在不更改bar的设计的情况下工作吗(例如,bar采用bar::bar()或bar保留std::istream&而不是std::unique_ptr<foo>还是通过向foo添加数据成员)?

解决方法

您的设计约束无法满足。最安全的放松方法是按住std::ifstream中的bar

class bar
{
     std::ifstream objs_stream;         // must be declared before obj
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : objs_stream(filename),obj(objs_stream)
   {}
   ...
};

另一种选择是向第三方课程提交补丁:

class foo
{
  public:
    explicit foo(std::istream&);
    explicit foo(std::istream&& is) : foo(is) {}
  ...
};

如果foo具有复制或移动构造函数,则可以

foo make_foo(const std::string& filename)
{
    std::ifstream is(filename);
    return foo(is);
}

class bar
{
     foo obj;                           // must not be altered
   public:
     explicit
     bar(std::string const&filename)    // must not be altered
       : obj(make_foo(filename))
   {}
   ...
};
,

我想出了以下可能性(编译时没有错误)。

class bar
{
    foo obj;                           // must not be altered
    struct tmp {
       mutable std::ifstream s;
       tmp(std::string const&f) : s(f) {}
       operator std::istream&() const { return s; }
    };
  public:
    explicit
    bar(std::string const&filename)    // must not be altered
      : obj(tmp(filename))
  {}
  ...
};

可以吗?即会一直生存到tmp::sobj的构造返回为止(根据foo的文档,请参见已编辑的问题,就足够了吗?)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...