构造函数按值接收两个参数时出错

Error in constructor receiving two parameters by value

本文关键字:两个 参数 出错 构造函数      更新时间:2023-10-16

有时我发现非常有用,为了简单和高效,使用这种类型的迭代器:

// Chunk 1
    template <class Itor1, class Itor2 = Itor1>
class Pair_Iterator
{
  Itor1 it1;
  Itor2 it2;
public:
  Pair_Iterator(Itor1 i1, Itor2 i2) : it1(i1), it2(i2) {}
  bool has_curr() const { return it1.has_curr() and it2.has_curr(); }
  auto get_curr() const
  {
    return std::make_pair(it1.get_curr(), it2.get_curr());
  }
  void next()
  {
    it1.next();
    it2.next();
  }
};

这个想法是通过其迭代器同时遍历两个可能属于不同类型的容器。

现在,由于我不明白的原因,下一个测试无法编译:

// previous chunk could be included here
struct It1
{
  It1() {}
  bool has_curr() const { return true; }
  int get_curr() const { return 1; }
  void next() {}
};
int main()
{
  for (Pair_Iterator<It1> it(It1(), It1()); it.has_curr(); it.next())
    ;
}

Clang 编译器(3.8 版)说:

error: member reference base type 'Pair_Iterator<It1> (It1 (*)(), It1 (*)())'
      is not a structure or union
  for (Pair_Iterator<It1> it(It1(), It1()); it.has_curr(); it.next())
                                            ~~^~~~~~~~~
it.C:57:62: error: member reference base type 'Pair_Iterator<It1> (It1 (*)(), It1 (*)())'
      is not a structure or union
  for (Pair_Iterator<It1> it(It1(), It1()); it.has_curr(); it.next())
                                                       ~~^~~~~

GNU编译器(5.3版)说:

error: request for member ‘has_curr’ in ‘it’, which is of non-class type ‘Pair_Iterator<It1>(It1 (*)(), It1 (*)())’
   for (Pair_Iterator<It1> it(It1(), It1()); it.has_curr(); it.next())
                                                ^
it.C:57:63: error: request for member ‘next’ in ‘it’, which is of non-class type ‘Pair_Iterator<It1>(It1 (*)(), It1 (*)())’
   for (Pair_Iterator<It1> it(It1(), It1()); it.has_curr(); it.next())

但是,如果我通过以下方式更改Pair_Iterator实例化:

It1 it1;
for (Pair_Iterator<It1> it(it1, It1()); it.has_curr(); it.next())

然后一切都完美编译。

所以我的问题是:

  1. 为什么第一个实例化无效(我认为是因为两个编译器拒绝它)
  2. 有没有办法写Pair_Iterator以便兴趣的实例化通过?

你已经加入了全世界数百万与最烦人的解析作斗争的人。

Pair_Iterator<It1> it(It1(), It1())

这被解释为一个函数,该函数将两个指针指向返回It1,然后返回一个Pair_Iterator<It1>。使用统一的初始化语法来解决它,或将它们括在额外的括号中。

Pair_Iterator<It1> it{It1(), It1()}

它在第二种情况下成功,因为It()是一个类型,后跟括号,所以它可能是一个函数类型。但是,变量的名称迫使编译器意识到它正在实例化一个新变量,而不是声明函数。


一般来说,当一个表达式看起来像type name(type(), type())时,它应该替换为:

type name{type(), type()}
//or
type name = type(type(), type())
//or
type name((type()), (type()))

type()参数的数量无关紧要; type name(type())type name(type(), type(), type())遇到同样的问题。