代码之家  ›  专栏  ›  技术社区  ›  Simon

C++/CLI值类约束无法编译。为什么?

  •  6
  • Simon  · 技术社区  · 16 年前

    几周前,我的一个同事花了大约两个小时发现为什么这段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 generics

    添加 ValueType 将使代码编译。

    public ref class Test
    {
        generic<class T> where T : value class, ValueType
            void MyMethod(Nullable<T> nullable)
        {
    
        }
    };
    

    我现在的问题是。为什么?两者有什么区别 value class 价值型 ?

    P.S:参见C++的可空定义: http://msdn.microsoft.com/de-de/library/b3h38hb0.aspx

    2 回复  |  直到 8 年前
        1
  •  5
  •   Simon    16 年前

    我分析了以下三种方法的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代码,我将其与.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
    {
    }
    

    这是IL声明 Nullable<T> :

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

    如您所见,只有第一个方法的约束与 可以为空<t> (BTW: value class 似乎意味着存在一个标准的构造函数)。然而,为什么编译器为相同的约束(语义上)生成不同的IL代码仍然是个谜。我将向微软的C++/CLI大师寻求进一步的信息。

        2
  •  0
  •   Lucero    16 年前

    ValueType 特殊之处在于它是值类型的“基类”,而不是值类型本身。这可能就是问题所在。

    可以在 this excellent blog post .

    也见 this this thread 有关 价值型 .

    推荐文章