为什么无法初始化“std::vector”?[复制]

Why the `std::vector` could not be initialised? [duplicate]

提问人:John 提问时间:5/2/2022 更新时间:5/2/2022 访问量:44

问:

下面是代码片段

#include <iostream>
#include <vector>

template <typename T>
class Point
{
    public:
        Point() = default;  
        Point(T x, T y):x_(x),y_(y){}
        //Point(const Point&) = delete;
        Point(Point&&) = default;
        T x_;
        T y_;
};

#define INIT_VECTOR

int main ()
{
#ifdef INIT_VECTOR
  std::vector<Point<int>> myvector={{1,1},{2,2}};   //why it does not compile?
#else
  std::vector<Point<int>> myvector;                //whereas, this works well.
  myvector.reserve(5);
#endif

  myvector.emplace_back();
  auto& point = myvector.back();
  point.x_ = 6;
  point.y_ = 9;

  std::cout << "myvector contains:" << std::endl;
  for (auto& pt: myvector)
  {
        std::cout << ' ' << pt.x_ << "," << pt.y_ << std::endl;
  }
  return 0;
}

很明显,它没有复制构造函数,而它有移动构造函数。 我的问题是为什么不编译? 有人可以澄清一下这件事吗?我想了又想,但还是想不通为什么。Point<T>std::vector<Point<int>> myvector={{1,1},{2,2}};

C++ C++11 Vector STL 复制构造函数

评论

0赞 ShadowRanger 5/2/2022
性能说明:非默认构造函数应为 ;当是像 这样的原始类型时,您不会花费任何费用,但如果您使用更昂贵的类型,例如 ,它会用廉价的所有权转移替换不必要的副本。Point(T x, T y):x_(std::move(x)),y_(std::move(y)){}Tintmpz_class
1赞 ShadowRanger 5/2/2022
可以肯定的是,这个问题的答案可以在initializer_list和移动语义中找到;这不是一个严格的重复,但它基本上是同一个问题(试图编写相同代码的人需要做同样的工作,但它不起作用)。不管你希望什么,s 通过迭代器进行迭代,所以它不能从迭代器移动到 ,它必须执行副本。您禁用了复制,因此它无法执行此操作。vectorinitializer_listconstvector
0赞 John 5/2/2022
@ShadowRanger 感谢您的指导。提出了一个问题,如果它写成 ,那么 应该有一个移动构造函数一个复制构造函数,而如果它写成 ,那么必须有一个复制构造函数。我说得对吗?x_(std::move(x)), y_(std::move(y)Tx_(x), y_(y)T
0赞 ShadowRanger 5/2/2022
是的。实际的或传递给构造函数的构造函数可能应用了其中任何一个,或者当调用者在调用本身中构造对象时完全避免复制/移动构造,具体取决于调用者如何调用它(因此,如果对象没有复制构造函数,则调用者将不得不向它传递一个新构造的值,以完全省略复制/移动构造)。但是在函数中,你有控制权,移动意味着如果它支持复制或移动构造,你就会支持它。xystd::move
0赞 ShadowRanger 5/2/2022
(综上所述,我的 C++ 专业知识不足以说明编译器是否只需要复制或移动构造的能力,然后实际上完全省略所有临时值;我有点希望他们会,但我经常对这些事情感到失望)

答: 暂无答案