我有一个用于数学的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.
}
}
如何解决?
答案 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
类型的数据的定义。如果它的重量足够大,您可以考虑通过引用进行调用以节省复制对象的时间,那么也许应该将其更改为引用类型。