【问题标题】:Why does the statement “vector<int>(v1);” fail为什么语句“vector<int>(v1);”失败
【发布时间】:2016-04-01 15:32:34
【问题描述】:

vector&lt;int&gt;(v1) 表达式产生一个临时对象,并且可以放在operator= 的右侧,但是如果我们使用vector&lt;int&gt;(v1) 表达式作为语句,它将在 Visual Studio 2010 10.0.30319.1 RTMRel 中失败.详细的错误信息在以下代码中的 cmets 中。为什么会这样?

vector<int> v1; 
v1.push_back( 10 );
v1.push_back( 20 );
v1.push_back( 30 );    
vector<int> v3 = vector<int>(v1);  //OK, deliberately code like this.
vector<int>(v1);  //error C2086: “std::vector<_Ty> v1”: redefinition

“C++ 编码标准:101 条规则、指南和最佳实践”一书中,第 82 章“使用公认的习语真正缩小容量并真正擦除元素”。有一个说法:

container<_Type>(c).swap(c);

看不懂,只想测试container&lt;_Type&gt;(c),是什么意思?

【问题讨论】:

  • 请在代码行前使用四个空格将其标记为代码,并添加换行符(用于以后的帖子,因为@Yu Hao已经编辑了您当前的帖子)
  • "如果我们使用vector(v1) 表达式作为语句,[它失败]" -- 好的,但你为什么要这样做?你想完成什么?
  • 您为什么认为这是一个有效的声明?你预计它会产生什么影响?
  • 这是歧义解决的结果。如果一个构造可以被解析为一个声明,那么它就是一个声明

标签: c++ vector


【解决方案1】:

vector&lt;int&gt;(v1);vector&lt;int&gt; v1; 相同。即变量重定义。

【讨论】:

  • 这些愚蠢的括号的原因是您需要它们来处理更复杂的情况,例如std::vector&lt;int&gt; (*pFunc)(std::list&lt;int&gt;)*pFunc 一起使用,而不是std::vector&lt;int&gt;
【解决方案2】:

vector&lt;int&gt;(v1) 表达式产生一个临时对象,可以放在operator= 的右侧,但是如果我们使用vector&lt;int&gt;(v1) 表达式作为语句,我们会失败...

编译器对普通语句的处理方式不同:

vector<int>(v1); //error C2086: “std::vector<_Ty> v1”: redefinition

是另一种写法

vector<int> v1;

所以你正在重新定义 v1 并且编译器会抱怨。


例如查看您的临时初始化工作使用情况

void foo(const std::vector<int>& v)
{
}

并调用

foo(vector<int>(v1));

或者干脆1

(std::vector<int>)(v1); // this creates a temporary which is immediately disposed

See live demo for the latter


1)盗自@Sergey Aanswer,但他更喜欢删除它

【讨论】:

    【解决方案3】:

    我知道vector&lt;int&gt;(v1) 是违反直觉的,但我不明白使用它的意义。正如其他人指出的那样,这是标准行为。如果您正在寻找解决方案,这里有 2 种解决方法:

    vector<int>::vector( v1 );
    vector<int> { v1 };
    

    EDIT(问题变了):container&lt;_Type&gt;(c).swap(c);我不明白...”这与container&lt;_Type&gt;(c);不同。容器的容量可能大于通过size 报告的容量(请参阅reserve)。储备有助于最大限度地减少某些操作的数量。如果添加新元素,容器将使用已分配的内存。例如,您的向量可能有 10 个元素的空间,但实际上只有 1 个。如果添加一个新元素,则剩下 8 个元素的空间。上述构造删除了保留以节省内存。首先制作原件的副本(此副本没有保留)。然后,原始向量的底层数据(指针)被新向量替换(参见swap),并且临时对象(现在拥有原始向量的内存)被丢弃。

    "...去测试container&lt;_Type&gt;(c),是什么意思?" 如上使用的意思是"创建一个c的临时副本"。单独使用,它看起来像一个复制构造函数,但实际上它声明了一个对象。差异由点运算符给出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-20
      • 1970-01-01
      • 2017-06-22
      • 2016-01-17
      • 2021-12-10
      • 2021-03-04
      • 1970-01-01
      相关资源
      最近更新 更多