【问题标题】:Selecting overload with tracking reference使用跟踪参考选择过载
【发布时间】:2014-06-03 14:02:58
【问题描述】:

在 C# 中,我可以编写执行以下操作的代码:

void Add(Vector3 a, Vector3 b, out Vector3 c)
{
  Add(ref a, ref b, out c);
}

void Add(ref Vector3 a, ref Vector3 b, out Vector3 c)
{
  c.X = a.X + b.X;
  c.Y = a.Y + b.Y;
  c.Z = a.Z + b.Z;
}

但是,在 C++/CLI 中,编译器(可以理解)无法选择正确的重载:

void Add(Vector3 a, Vector3 b, [Out] Vector3% c)
{
  Add(a, b, c);
}

void Add(Vector3% a, Vector3% b, [Out] Vector3% c)
{
  c.X = a.X + b.X;
  c.Y = a.Y + b.Y;
  c.Z = a.Z + b.Z;
}

如何向编译器表明我希望它选择第二个重载?

【问题讨论】:

  • C++/CLI 没有相应的语法。您需要稍微调整一下本机 C++,.NET 中存在值类型以使代码更高效。它们应该按值传递,这允许它们存储在 CPU 寄存器中。无论如何,您的 Add() 函数将始终由优化器内联。
  • 如果它的效率那么高,我会感到困惑的是,微软的 XNA 有他们所有的数学 API 的形式,它们通过 ref 获取向量等。但是,是的,我明白你的意思,至少当我们处理像向量这样的较小结构时——但是矩阵呢?按值传递仍然有效吗?
  • 另外,这是否意味着 C++/CLI 无法使用 XNA,考虑到所有数学 API 都会给出模棱两可的重载错误? (编辑:我现在发现我没有记错;他们的 Vector3 API 不采用 ref 向量,但他们的矩阵 API 可以)。
  • 当然,这是一个 XNA 问题。它们违反了强大的 .NET 设计准则,结构的成员不应超过 4 个。超越会扼杀它们的价值,你应该切换到一个类。顺便说一句,不寻常的错误。
  • 好的,我已经回答了我明天会接受的问题,除非你回答。非常感谢。 :)

标签: .net visual-c++ c++-cli overloading


【解决方案1】:

正如 Hans Passant 在对我的帖子的评论中所说,这是不可能的。值类型的要点是它们应该足够小以便有效地复制,如果不是,它们不应该是值类型。因此几乎在所有情况下都不需要第二次重载。

编辑:汉斯所说的并不完全正确。这会生成(几乎)与 C# 版本完全相同的 IL(不同之处在于它添加了 modopt([mscorlib]System.Runtime.CompilerServices.IsExplicitlyDereferenced)):

void Add(Vector3 a, Vector3 b, [Out] Vector3% c)
{
  Add(&a, &b, c);
}

void Add(interior_ptr<Vector3> a, interior_ptr<Vector3> b, [Out] Vector3% c)
{
  c.X = a->X + b->X;
  c.Y = a->Y + b->Y;
  c.Z = a->Z + b->Z;
}

【讨论】:

    猜你喜欢
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    相关资源
    最近更新 更多