Visual studio 2015 C++/将唯一的\u ptr传递给虚拟函数时CLI编译器出现错误? >下面的代码编译为C++时工作良好,但编译为C++ +CLI时(例如,代码>/CLR )导致访问冲突(System .Access违规)。在这两种情况下,代码编译和链接都没有错误或警告(/W4)

Visual studio 2015 C++/将唯一的\u ptr传递给虚拟函数时CLI编译器出现错误? >下面的代码编译为C++时工作良好,但编译为C++ +CLI时(例如,代码>/CLR )导致访问冲突(System .Access违规)。在这两种情况下,代码编译和链接都没有错误或警告(/W4),visual-studio-2015,c++-cli,unique-ptr,virtual-functions,Visual Studio 2015,C++ Cli,Unique Ptr,Virtual Functions,c->g(std::move(p))(节选) 问题似乎在于,在调用函数之前,参数创建的临时唯一\u ptr被销毁。这在调用虚拟函数(C::g和C::k)时发生,但在调用非虚拟函数(C::h和::g)时不会发生。无论调用代码是非托管类(struct)还是托管类(ref struct)的一部分,都会发生这种情况。如果我用#pragma unmanaged包装类,则不会发生这种情况。(示例代码编译为非托管C++,当然,仅当不使用C++或CLI仅是特性时)。 有些相关:,但我的代码链接很好 问题:这是编

c->g(std::move(p))(节选)

问题似乎在于,在调用函数之前,参数创建的临时唯一\u ptr被销毁。这在调用虚拟函数(
C::g
C::k
)时发生,但在调用非虚拟函数(
C::h
::g
)时不会发生。无论调用代码是非托管类(
struct
)还是托管类(
ref struct
)的一部分,都会发生这种情况。如果我用
#pragma unmanaged
包装类,则不会发生这种情况。(示例代码编译为非托管C++,当然,仅当不使用C++或CLI仅是特性时)。 有些相关:,但我的代码链接很好

问题:这是编译器中的错误吗?如果是,这是一个已知的错误吗?如果不是,这是C++/CLI的已知限制吗?或者,代码中有错误?如果是编译器错误或限制,是否有(最好是简单的)不更改函数签名的解决方法(如中所建议)

(生成的代码:虽然我熟悉汇编程序,但在调试器显示的C++/CLI编译过程的反汇编过程中,我不理解对虚拟函数的调用在哪里。在调试时,我只进入所有唯一的_ptr内容,而不是函数调用…)

(背景:调用代码,托管类,是C代码和非托管C++库之间的桥梁)。 使用:
Microsoft Visual Studio Professional 2015版本14.0.25425.01更新3
Visual Studio 2015(v140)工具集
Microsoft.NET Framework版本4.6.01038
也因以下原因失败:
版本14.0.24720.00更新1

#include <memory>
#include <iostream>
using namespace std;

struct A
{
    virtual ~A() { cout << "~A()" << endl; }
};

struct I
{
    virtual void g(std::unique_ptr<A> p) = 0;
};

struct C : public I
{
    virtual void g(std::unique_ptr<A> p) override { cout << "C::g()" << endl; }
    void h(std::unique_ptr<A> p) { cout << "C::h()" << endl; }
    virtual void k(std::unique_ptr<A> p) { cout << "C::k()" << endl; }
};

void g(std::unique_ptr<A> p) { cout << "g()" << endl; }

//#pragma unmanaged
/*public ref*/ struct B
{
    void bug(I * c) {
        std::unique_ptr<A> p(new A);
        c->g(std::move(p)); // *p destroyed before reaching g() when /clr
    }
    void bug2(C * c) {
        std::unique_ptr<A> p(new A);
        c->k(std::move(p)); // *p destroyed before reaching g() when /clr
    }
    void ok() {
        std::unique_ptr<A> p(new A);
        g(std::move(p));
    }
    void ok(C * c) {
        std::unique_ptr<A> p(new A);
        c->h(std::move(p));
    }
};
//#pragma managed

int main()
{
    auto b = /*gcnew*/ new B;
    b->ok();
    C c;
    b->ok(&c);
    b->bug(&c);
    b->bug2(&c);

    return 0;
}
#包括
#包括
使用名称空间std;
结构A
{

虚拟~A(){你必须在连接MySoStcom上记录代码生成器bug,而不是你之前发现的。不确定他们会考虑修复它,这是使用标准C++模板类的一种非常丑陋的方法。除了调用栈中清晰可见的双中继之外,这样的代码确实需要非托管优化器才能获得高效。已经知道解决方法,转移到另一个翻译单元或明智地使用#pragma managed(push,off)。这显然也会影响将unique_ptr传递给派生类的构造函数(VS 2015 Update 3)。