为啥 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译

Posted

技术标签:

【中文标题】为啥 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译【英文标题】:Why does vector.push_back(System::Byte) not compile any more in VC++ 14.29 (C++/CLI)为什么 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译 【发布时间】:2021-06-01 04:32:55 【问题描述】:

我有以下代码用于编译和工作正常:

std::vector<unsigned char> marshal_as(cli::array<System::Byte>^ const& from) 

    std::vector<unsigned char> result;
    result.reserve(from->Length);
    for (int i = 0; i < from->Length; i++)
    
        result.push_back(from[i]);
    
    return result;

在将 VisualStudio 更新到 16.10 版(将 C++ 编译器更新到 14.29 版)后,代码会产生错误:

错误 C2664: 'void std::vector>::push_back(const _Ty &)': 无法转换 参数 1 从 'unsigned char' 到 'const _Ty &' 和 [ _Ty=无符号字符 ]

消息:来自 gc 堆的对象(托管数组的元素)无法转换为本机引用

消息:见 'std::vector>::push_back' 和 [ _Ty=无符号字符 ]

将循环体中的代码改为

    unsigned char b = from[i];
    result.push_back(b);

解决问题。

我想了解此错误的原因。这是否与 C++ 20 标准的变化有关?

【问题讨论】:

你也可以使用result.push_back((unsigned char)from[i]); @Frank 不,这会产生相同的错误消息 这是一个 C++ 问题吗:std::vector&lt;unsigned char&gt; result(reinterpret_cast&lt;const unsigned char*&gt;(from.data()), std::next(reinterpret_cast&lt;const unsigned char*&gt;(from.data()), from.size())); - 但不是,所以我将删除 C++ 标记。 @KlausGütter Weird,我刚刚将我的 Visual Studio 更新到 16.10 来测试这一点,result.push_back((unsigned char)from[i]); 绝对让我的问题消失了。 【参考方案1】:

这是否与 C++ 20 标准的变化有关?

没有。虽然 std::vector&lt;&gt;::push() 在 C++20 中发生了微妙的变化,但这并没有对这里发生的事情产生重大影响,这个问题绝对是 clr 特定的。

我想了解这个错误的原因。

这几乎可以肯定(见下文)始终存在于您的代码中,但以前版本的 C++/CLI 编译器并未报告此错误。

考虑以下函数:

void foo(const int& v) 
  int* ptr = &v;
  // store ptr somewhere, long-term.

很明显,通过引用 gc 支持的 int 来调用 foo() 将导致灾难。然而,这正是result.push_back(from[i]); 所做的。

您的代码“有效”,因为push_back() 碰巧没有对其参数执行任何操作,从而导致问题。但是,编译器不应该知道

注意我说几乎可以肯定,因为我在追踪 cli::array&lt;T&gt;::operator[](std::size_t) const 的呼叫签名时有很长的时间。以前返回T,现在返回const T%也不是不可能。

【讨论】:

确实,operator[](array&lt;unsigned char&gt;^, int) const 返回unsigned char% @KlausGütter,对,现在剩下的问题是:改变了吗? 用 VS 16.9.2 检查:operator[](array&lt;unsigned char&gt;^, int) const 没有改变。所以行为改变似乎确实在编译器中。

以上是关于为啥 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译的主要内容,如果未能解决你的问题,请参考以下文章

在展开期间将向量成员推入向量:vector.push_back(vector[0])

std::vector.push_back() 的奇怪(记忆?)问题

正确使用用户定义类型的 std::vector.push_back()

std::vector::emplace_back 比 std::vector::push_back 慢的示例?

Vector::push_back() 给出读取访问冲突

指针定义后 C++ vector.push_back 崩溃