c++ /CLI上的值结构实现了一个有where t: struct约束的接口,导致编译器崩溃

本文关键字:struct 约束 where 接口 崩溃 编译器 结构 CLI 实现 c++ 一个 | 更新日期: 2023-09-27 18:02:53

在c++/CLI中实现值类型结构上的接口时遇到问题,其中接口上的一个方法恰好有一个需要ref的方法签名。我相信我使用了正确的语法,但是编译器崩溃了。我让它编译的唯一方法是通过删除where约束。我在c++/CLI中的语法有什么问题,一定是做错了:

解决方案TestSomething.sln:

  1. 在解决方案中创建c#类库项目,包含一个名为Class1.cs的文件,其内容如下(a)。我将库命名为"Blah"
  2. 在解决方案中创建c++/CLI控制台应用程序,包含一个名为TestStruct.h的文件,其内容如下(B)。我将控制台项目称为"ValueStructInterfaceIssueCppCli"
  3. 构建解决方案,它将生成以下错误:

Error 1 Error C1001:编译器发生内部错误。f:'valuestructinterfaceissuecppcli'TestStruct.h 22 1 valuestructinterfaceissuecppcli

在c#中我有一个非常简单的接口,这是一个c#类库项目,字面上只是一个文件。

Class1.cs (A)目录

using System;
namespace Blah
{
    public interface IHoopie<T> where T : struct
    {
        void DoSomething(ref T source);
    }
}

然后我用c++在一个值结构上实现这个接口,很简单:

这是在一个c++/CLI控制台应用程序中,在相同的解决方案中有一个c#类库"blah"的项目引用。

teststructure .h (B) Contents

#pragma once
using namespace System;
namespace Blah
{
public value struct TestStruct : public IHoopie<TestStruct> 
{
public:
    double X;
    double Y;
    double Z;
    virtual void DoSomething(TestStruct% source)
    {
        X = 1;
        Y = 2;
        Z = 3;
    };
};
}

然而,当我试图在VS 2010 (sp1)中实现c++/CLI中的接口时,编译器崩溃了,我也试图在VS 2015(更新3)中抱怨同样的事情。

错误2错误C1001:一个内部错误发生在编译器..'valuestructinterfaceissuecppcli'TestStruct.h 22 1 valuestructinterfaceissuecppcli

我需要将我的接口限制为值类型,然而,就像测试一样,我删除了c#接口中的where约束,如以上c++代码,然后遵从编译得很好:

public interface IHoopie<T> 
{
    void DoSomething(ref T source);
}

作为另一个测试,我在c++/CLI中使用了"refstruct",这也有效。无论出于何种原因,我不能在c#中使用"where T: struct",然后在c++/CLI中实现值结构。看起来很奇怪。我相信我在c++/CLI中使用了正确的格式:

virtual void DoSomething(TestStruct% source)

%对于通过引用传递值类型是正确的,它应该很好,但我不明白为什么它不能编译。

对于简单地删除c#中的where约束,我也有一些顾虑。如果T碰巧是一个对象,那么语法TestStruct%源是不正确的,它必须是TestStruct%^当T是int时,例如"%^"不会工作,除非我错过了一些东西

更新! !

rob在评论中提到的一些事情给了我一个想法。我修改了代码,为T使用了不同的结构,如下所示:

teststructure .h (B) Contents

public value struct SomeStruct
{
public:
    double x;
};
public value struct TestStruct : public IHoopie<SomeStruct> 
{
private:
    double last_;
public:
    double X;
    double Y;
    double Z;
    virtual void DoSomething(SomeStruct% source)
    {
        X = 1;
        Y = 2;
        Z = 3;
    };
};

修复了编译器崩溃....有趣。得把这事搞清楚。将张贴回来,如果这是答案。我的猜测(而不是一个好的)是,在c++/CLI它有一些问题使用结构体在。h文件作为T在自己的声明?这可能就是导致编译器崩溃的原因。

请记住,在c#中这是完全合乎逻辑的。我说在结构定义中,我希望TestStruct实现一个名为DoSomething的方法,它通过引用自身的值类型。在上下文中,也许这是一个可能的用例(假设DoSomething被称为Copy)

Copy(ref TestStruct source) { /* do some copying */ }

c++ /CLI上的值结构实现了一个有where t: struct约束的接口,导致编译器崩溃

在您的实现之上添加IHoopie实现似乎可以避免编译器错误。我不知道为什么。

#pragma once
using namespace System;
namespace Blah
{
public value struct HoopieAdapter : public IHoopie<int> {
    public: virtual void DoSomething(int% source) {}
};
public value struct TestStruct : public IHoopie<TestStruct> 
{
public:
    double X;
    double Y;
    double Z;
    virtual void DoSomething(TestStruct% source)
    {
        X = 1;
        Y = 2;
        Z = 3;
    };
};
}

不是真的,但是Lucas和ebyrob在下面的评论中给了我一些想法:

基于用int或其他结构体替换TestStruct的发现编译器不再崩溃....说明更多的只是一些编译器问题。为了证明这一点,我使用了4.6.1而不是4.0,看看它是否被修复了

重新尝试了我在帖子中提到的原始测试。它DOES在。net 4.6.1和C+/CLI中编译得很好。@Lucas ->看起来像一个编译器错误。也不会在VS 2010明显修复,但我知道什么。至少在4.6.1中修复。

所有这些理论都是由ebyrob带来的,所以谢谢ebyrob把我引向了另一个方向,尽管这是Lcuas指出的完全有效的语法,但仍然让我走上了道路。

再次感谢大家