为什么 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)
我有以下用于编译和工作正常的代码:
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 - 代码产生错误:
error C2664: 'void std::vector<unsigned
char,std::allocator<_Ty>>::push_back(const _Ty &)': cannot convert
argument 1 from 'unsigned char' to 'const _Ty &'
with
[
_Ty=unsigned char
]
message : An object from the gc heap (element of a managed array) cannot be converted to a native reference
message : see
declaration of 'std::vector<unsigned
char,std::allocator<_Ty>>::push_back'
with
[
_Ty=unsigned char
]
将循环体中的代码更改为
unsigned char b = from[i];
result.push_back(b);
解决了问题。
我想了解这个错误的原因。这在某种程度上与 C++ 20 标准引起的变化有关吗?
Is this somehow related to a change due to the C++ 20 standard?
没有。虽然 std::vector<>::push()
在 C++20 中发生了微妙的变化,但这并不是对这里发生的事情产生实质性影响的变化,这个问题肯定是特定于 clr 的。
I would like to understand the cause of this error.
这几乎可以肯定(见下文)是您的代码中始终存在的错误,但以前版本的 C++/CLI 编译器未报告。
考虑以下函数:
void foo(const int& v) {
int* ptr = &v;
// store ptr somewhere, long-term.
}
很明显,调用 foo()
并引用 gc-backed int
将导致灾难。然而,这正是 result.push_back(from[i]);
所做的。
您的代码“有效”,因为 push_back()
碰巧对其参数没有执行任何操作,这导致了问题。但是,编译器不应该知道。
N.B. 我几乎可以肯定地说是因为我花了大量时间来追踪 cli::array<T>::operator[](std::size_t) const
的调用签名。以前 return a T
和现在 returns const T%
.
也不是不可能
我有以下用于编译和工作正常的代码:
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 - 代码产生错误:
error C2664: 'void std::vector<unsigned char,std::allocator<_Ty>>::push_back(const _Ty &)': cannot convert argument 1 from 'unsigned char' to 'const _Ty &' with [ _Ty=unsigned char ]
message : An object from the gc heap (element of a managed array) cannot be converted to a native reference
message : see declaration of 'std::vector<unsigned char,std::allocator<_Ty>>::push_back' with [ _Ty=unsigned char ]
将循环体中的代码更改为
unsigned char b = from[i];
result.push_back(b);
解决了问题。
我想了解这个错误的原因。这在某种程度上与 C++ 20 标准引起的变化有关吗?
Is this somehow related to a change due to the C++ 20 standard?
没有。虽然 std::vector<>::push()
在 C++20 中发生了微妙的变化,但这并不是对这里发生的事情产生实质性影响的变化,这个问题肯定是特定于 clr 的。
I would like to understand the cause of this error.
这几乎可以肯定(见下文)是您的代码中始终存在的错误,但以前版本的 C++/CLI 编译器未报告。
考虑以下函数:
void foo(const int& v) {
int* ptr = &v;
// store ptr somewhere, long-term.
}
很明显,调用 foo()
并引用 gc-backed int
将导致灾难。然而,这正是 result.push_back(from[i]);
所做的。
您的代码“有效”,因为 push_back()
碰巧对其参数没有执行任何操作,这导致了问题。但是,编译器不应该知道。
N.B. 我几乎可以肯定地说是因为我花了大量时间来追踪 cli::array<T>::operator[](std::size_t) const
的调用签名。以前 return a T
和现在 returns const T%
.