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 classValueType有什么区别?

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&lt;T&gt;的IL声明:

.class public sequential ansi serializable sealed beforefieldinit 
Nullable<valuetype (System.ValueType) .ctor T>
    extends System.ValueType

如您所见,只有第一种方法的约束与Nullable&lt;T&gt; 的约束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 为啥对托管不可见

为啥我们不能将本地 C++ 的引用传递给 C++/CLI?

为啥 C++ CLI 索引属性在 C# 中不起作用?

Mono .NET 是不是支持和编译 C++/CLI?

在 C++/CLI 中使用 std::basic_ifstream::get() 时出现 AccessViolationException,为啥?