C++/CLI中声明std::vector<System::Decimal>出现C3699错误求助
问题描述
在C++/CLI开发Windows Forms程序时,以下代码可正常编译:
private: std::vector<System::Int32>* test = new std::vector<System::Int32>;
但声明std::vector<System::Decimal>时出现编译错误:
private: std::vector<System::Decimal>* test = new std::vector<System::Decimal>;
错误信息:
1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vector(874,39): error C3699: '&&': cannot use this indirection on type '_Ty' 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vector(874,39): error C3699: with 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vector(874,39): error C3699: [ 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vector(874,39): error C3699: _Ty=System::Decimal 1>C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.39.33519\include\vector(874,39): error C3699: ]
问题原因
System::Int32虽是托管值类型,但和原生C的int等价,编译器会自动隐式转换,STL容器可像处理原生类型一样兼容它。而System::Decimal是CLR特有的托管值类型,无对应原生C类型,且不支持原生C++的右值引用(&&)操作——STL容器的内部实现(如移动构造、赋值)依赖这些原生特性,因此触发编译错误。
解决方案
方案1:使用CLR托管容器(推荐)
在C++/CLI环境中,优先使用.NET框架提供的托管容器存储托管类型,比如System::Collections::Generic::List<T>:
private: System::Collections::Generic::List<System::Decimal>^ test = gcnew System::Collections::Generic::List<System::Decimal>;
托管容器完全适配CLR的内存管理和类型系统,不会出现原生容器的兼容性问题。
方案2:将托管Decimal包装为可兼容的非托管类型
如果必须使用std::vector,可通过以下方式处理:
- 转换为
double存储(注意存在精度损失):
private: std::vector<double>* test = new std::vector<double>; // 使用时转换:System::Decimal dec = ...; test->push_back(static_cast<double>(dec));
- 自定义结构体存储Decimal内部字段(需了解Decimal的内存结构):
struct NativeDecimal { int32_t flags; int32_t hi; int32_t lo; int32_t mid; }; private: std::vector<NativeDecimal>* test = new std::vector<NativeDecimal>; // 使用时转换:System::Decimal dec = ...; pin_ptr<System::Decimal> pDec = &dec; memcpy(&nd, pDec, sizeof(NativeDecimal)); test->push_back(nd);
这种方式复杂度较高,仅适用于特殊场景。
内容的提问来源于stack exchange,提问作者dkmg
相关产品推荐
相关产品推荐

