C++ cli 隐式用户定义的强制转换运算符(有时)不适用于常量类型 我试图让我们的C++和我们.NET代码之间的一些IJW包装更容易使用。

C++ cli 隐式用户定义的强制转换运算符(有时)不适用于常量类型 我试图让我们的C++和我们.NET代码之间的一些IJW包装更容易使用。,c++-cli,C++ Cli,以下是我们的包装器平台的测试情况: // NativeWrapper.h #pragma once template <class T> public ref class NativeWrapper { public: // ... operator T* (); operator T& (); // ... }; // Test.h #pragma once class Test { /* ... */ }; #pragma make_pu

以下是我们的包装器平台的测试情况:

// NativeWrapper.h
#pragma once
template <class T>
public ref class NativeWrapper
{
public:
    // ...
    operator T* ();
    operator T& ();
    // ...
};

// Test.h
#pragma once
class Test { /* ... */ };
#pragma make_public( Test )

// TestN.h
#pragma once
#include "NativeWrapper.h"
#include "Test.h"

public ref class TestN : public NativeWrapper<Test>
{ /* ... */ };

// main.cpp
#include "TestN.h"

void f(const Test&) { /* ... */ }

int main()
{
    TestN^ t = gcnew TestN();
    f(t);
    return 0;
}
我无法识别我在测试中所做的与我在主代码库中所做的之间的任何根本区别。NativeWrapper模板是相同的

当唯一可接受的类型是常量引用类型时,哪些类型的情况可能会导致编译器无法使用非常量转换运算符


谢谢。

您没有发布真正说明您的问题的代码。不得不猜测,您正在做一件非常危险的事情,并且成功地击败了一个重要的编译时检查。t变量是对托管对象的引用,当垃圾收集器压缩堆时,托管对象可以在内存中移动。当f()函数执行时,这是灾难性的,因为它保留了对对象的非托管引用,而该对象不再是它以前所在的位置。这种故障模式非常恶劣,不可能调试,因为这种情况很少发生。永远不要这样做。谢谢你,汉斯。不幸的是,我现在无法发布代码来演示我的问题,因为我无法区分生成编译器错误的代码和上面的工作测试代码。当我设法生成一个好的代码块进行比较时,我想我会用更好的信息重新发布这个问题。cast操作符返回的引用实际上是对本机堆上的对象的引用,因此我认为这不会有风险。我的假设错了吗?
f((Test&)t);