检查初始化列表中的空向量

Posted

技术标签:

【中文标题】检查初始化列表中的空向量【英文标题】:Check empty vector in initializer list 【发布时间】:2015-03-12 10:34:03 【问题描述】:

我想通过包含基类的向量的第一项来初始化基类,例如:

struct Base  ... ;

struct Derived : public Base

   Derived(const Base& baseClass)
      : Base(baseClass)
   
   
   Derived(const std::vector<Base*>& listOfBaseClass)
      : Base(*(listOfBaseClass[0]))
   
   
;

listOfBaseClass 向量为空时,此解决方案将失败。怎样才能防止这种情况。这是一个简化的例子,所以 像这样调用基类构造函数:

std::vector<Base> baseClasses;

if(!baseClasses.empty())

  Derived myDerived(baseClasses[0]);

这不是我的问题的解决方案。提前致谢。

【问题讨论】:

【参考方案1】:

如果列表为空则抛出异常:

 : Base(listOfBaseClass.empty() 
          ? throw std::invalid_argument("Missing base class")
          : *(listOfBaseClass[0])
        )

请求的非异常变体:

 : Base(( (listOfBaseClass.empty() && exit(0)),
          *(listOfBaseClass[0])
       ))

【讨论】:

不幸的是,在我的项目中我不能使用异常。 好吧,那你有问题了。异常正是为这种情况设计的(在构造函数内部失败),而 C++ 没有其他选择(人们已经抱怨 C++ 很复杂,添加冗余特性来解决愚蠢的限制无济于事)。我建议你不要用错误的参数调用Derived @rgb,您已经接受了这个答案(否则我会发布一个新答案)。当对象的构造很重要时,规范的解决方案是工厂函数。该函数将在基类列表中查找并初始化要返回的类,如果没有,它将是应该抛出/退出/信号错误/等的工厂函数。 @utnapistim:我不认为它是规范的。它更像是一种 Java 主义。当甚至不清楚您需要什么类型对象时,C++ 通常会使用工厂。 @MSalters,考虑 std::make_shared、std::make_unique、std::make_tuple、std::make_pair - 你知道所有的结果类型。无论哪种方式,我都提出了工厂函数解决方案,因为我认为您不应该在库/服务器代码中调用 exit,并且添加工厂函数(如 create_x_or_exit)比添加(可能)失败的构造函数更容易.【参考方案2】:
Derived(const std::vector<Base*>& listOfBaseClass)
      : Base(*(listOfBaseClass->at(0)))
   
   

“at”提供异常安全性。如果 n 超出范围,它会抛出 out_of_range。

http://www.cplusplus.com/reference/vector/vector/at/

【讨论】:

以上是关于检查初始化列表中的空向量的主要内容,如果未能解决你的问题,请参考以下文章

大括号封闭初始化列表?转换为矢量

用向量的向量的元素初始化向量的空向量

为啥使用 null 函数而不是 == [] 来检查 Haskell 中的空列表?

将字符串列表插入二维向量

使用初始化列表创建单项向量

我可以在初始化列表中用 10 个相同的整数初始化 STL 向量吗?