为啥 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<unsigned char> result(reinterpret_cast<const unsigned char*>(from.data()), std::next(reinterpret_cast<const unsigned char*>(from.data()), from.size()));
- 但不是,所以我将删除 C++ 标记。
@KlausGütter Weird,我刚刚将我的 Visual Studio 更新到 16.10 来测试这一点,result.push_back((unsigned char)from[i]);
绝对让我的问题消失了。
【参考方案1】:
这是否与 C++ 20 标准的变化有关?
没有。虽然 std::vector<>::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<T>::operator[](std::size_t) const
的呼叫签名时有很长的时间。以前返回T
,现在返回const T%
也不是不可能。
【讨论】:
确实,operator[](array<unsigned char>^, int) const
返回unsigned char%
@KlausGütter,对,现在剩下的问题是:改变了吗?
用 VS 16.9.2 检查:operator[](array<unsigned char>^, 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()