C ++ / CLI ref参数重载

时间:2018-09-06 03:39:58

标签: c++-cli

我有一个用于数学的C ++ / CLI值类(C#中的结构)。

如您所知,与数学相关的结构经常使用ref参数作为其提高性能的方法。然后,为了方便起见,添加非ref版本的重载。

类似于这样,在C#中

public struct Vector
{
    public static Vector Add(Vector left, Vector right) => Add(ref left, ref right);
    public static Vector Add(ref Vector left, ref Vector right)
    {
        // Something.
    }
}

另一方面,在C ++ / CLI中,我制作了ref这样的版本,如下所示。

public value class Vector
{
public:
    static Vector Add(Vector% left, Vector% right)
    {
        // Something.
    }
}

没有问题。在C#项目中正确暴露了ref参数。

顺便说一句,非ref版本的情况如何。 我可以声明其原型,但不能从中调用ref版本。

public value class Vector
{
public:
    static Vector Add(Vector left, Vector right)
    {
         return Add(left, right); // Compile error C2668.
    }
    static Vector Add(Vector% left, Vector% right)
    {
        // Something.
    }
}

如何解决?

1 个答案:

答案 0 :(得分:0)

您在这里的目标是什么?

如果您的目标是拥有一个可以从C ++ / CLI调用的API,那么忽略了如何实现这两个版本的问题,您将如何从C ++ / CLI代码中调用它们呢?由于C ++ / CLI在调用ref版本时不需要额外的关键字,因此在尝试使用Add的任何地方都会出现错误C2668。在这种情况下,我将用不同的名称实现这两个版本。

如果您的目标是拥有一个可以从C#调用的API,那么使这两个方法具有相同的名称可能很有意义,因为C#可以根据ref关键字来区分要调用的方法。在这种情况下,我将实现Add(Vector, Vector)Add(Vector%, Vector%)作为调用私有方法AddImpl(Vector%, Vector%)两者

我没有使用编译器进行检查。由于调用方法的方式如此相似,因此即使修复了实现,也可能会出现编译器错误。最后我检查了一下,一个非托管的C ++编译器甚至不允许您沿foo(int)foo(int&)的行定义重载,因为它们的调用方式完全相同。 (尽管我可能记错了。)


现在,所有这些,让我说,这对我来说就像过早的优化。考虑仅实现“按价值致电”版本,如果您的表现可以接受,那么就不需要这些额外的麻烦了。

此外,您还没有显示对Vector类型的数据的定义。如果它的重量足够大,您可以考虑通过引用进行调用以节省复制对象的时间,那么也许应该将其更改为引用类型。