C++/CLI 值类约束不会编译。为啥?
Posted
技术标签:
【中文标题】C++/CLI 值类约束不会编译。为啥?【英文标题】:C++/CLI value class constraint won't compile. Why?C++/CLI 值类约束不会编译。为什么? 【发布时间】:2010-05-16 13:31:48 【问题描述】:几周前,我的一位同事花了大约两个小时找出为什么这段 C++/CLI 代码无法使用 Visual Studio 2008 编译(我刚刚使用 Visual Studio 2010 对其进行了测试......同样的故事) .
public ref class Test
generic<class T> where T : value class
void MyMethod(Nullable<T> nullable)
;
编译器说:错误
1 错误 C3214:“T”:无效类型 泛型参数“T”的参数 通用 'System::Nullable',不 满足约束'System::ValueType ^' C:\Users\Simon\Desktop\Projektdokumentation\GridLayoutPanel\Generics\Generics.cpp 11 1 泛型
添加ValueType
将使代码编译。
public ref class Test
generic<class T> where T : value class, ValueType
void MyMethod(Nullable<T> nullable)
;
我的问题是现在。为什么? value class
和ValueType
有什么区别?
P.S:请参阅 C++ 的 Nullable 定义:http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx
【问题讨论】:
我同意,值类约束应该已经足够了。我认为您的解决方法是正确的。你可以试试 connect.microsoft.com 看看他们会说什么。 【参考方案1】:我分析了以下三种方法的IL代码:
generic<class T> where T : value class, System::ValueType
static void MyMethod(T arg)
generic<typename T> where T: value class
static void MyMethod2(T arg)
generic<typename T> where T: ValueType
static void MyMethod3(T arg)
对应的IL-code,我用.NET-Reflector反汇编的:
.method public hidebysig
static void MyMethod<valuetype ([mscorlib]System.ValueType).ctor T>
(!!T arg) cil managed
.method public hidebysig
static void MyMethod2<valuetype .ctor T>(!!T arg) cil managed
.method public hidebysig
static void MyMethod3<([mscorlib]System.ValueType) T>(!!T arg) cil managed
这是Nullable<T>
的IL声明:
.class public sequential ansi serializable sealed beforefieldinit
Nullable<valuetype (System.ValueType) .ctor T>
extends System.ValueType
如您所见,只有第一种方法的约束与Nullable<T>
的约束100% 匹配。 (顺便说一句:value class
似乎暗示了标准构造函数的存在)。然而,为什么编译器会为(语义上)相同的约束生成不同的 IL 代码,这仍然是一个谜。我会向微软的 C++/CLI 专家询问更多信息。
【讨论】:
【参考方案2】:ValueType
的特殊之处在于它是值类型的“基类”,而不是值类型本身。这可能是这里的问题。
可以在this excellent blog post 中找到 CLR 使用的不同实体的一个很好的列表。
另请参阅this 和this thread,了解更多关于ValueType
的信息。
【讨论】:
感谢您的研究,Lucero。以上是关于C++/CLI 值类约束不会编译。为啥?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译
在 C++/CLI 中使用 std::basic_ifstream::get() 时出现 AccessViolationException,为啥?