首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >消除模板函数专门化的歧义-值与引用

消除模板函数专门化的歧义-值与引用
EN

Stack Overflow用户
提问于 2022-03-13 15:55:22
回答 1查看 52关注 0票数 1

这个问题需要一些背景--如果你感到不耐烦,跳过底线.我有一个Vector-3,4Matrix-3,4库,定义为模板专门化;也就是说,Vector<n>Matrix<n>是在Matrix.hh中定义的,而非平凡的实现(例如矩阵乘法、矩阵逆)在Matrix.cc for N = {3,4}中有显式的专门化或实例化。

这种方法行之有效。理论上,应用程序可以实例化Matrix<100>,但不能乘以或反转矩阵,因为头部中没有可见的实现模板。只有N = {3,4}Matrix.cc中被实例化。

最近,我加入了稳健方法来补充任何涉及内积的运算--包括矩阵乘法、矩阵向量变换等。大多数3D变换(投影/方向)条件相对良好,任何微小的精度误差都不是问题,因为共享顶点/边会产生一致的栅格化。

有一些运算必须在数值上是稳健的。在渲染时,我不能对GPU如何做点积和矩阵操作做任何事情;但是我不能让控制/摄像机参数被有效的几何限制--而且内部产品因病理性消除错误而臭名昭著,所以稳健的方法使用补偿求和、积、点积等。

这对于Vector内部产品(比方说,Matrix.hh中的内部产品)来说很好:

代码语言:javascript
复制
////////////////////////////////////////////////////////////////////////////////
//
// inner product:


template <int n> float
inner (const GL0::Vector<n> & v0, const GL0::Vector<n> & v1)
{
    float r = v0[0] * v1[0];

    for (int i = 1; i < n; i++)
        r += v0[i] * v1[i];

    return r; // the running sum for the inner product.
}


float
robust_inner (const GL0::Vector<3> &, const GL0::Vector<3> &);

float
robust_inner (const GL0::Vector<4> &, const GL0::Vector<4> &);


////////////////////////////////////////////////////////////////////////////////

Matrix.cc中的实现是不平凡

当添加一个健壮的[A]<-[A][B]矩阵乘法方法时,我处于一个更不确定的领域;也许命名并不理想:

代码语言:javascript
复制
template <int n> GL0::Matrix<n> &
operator *= (GL0::Matrix<n> & m0, const GL0::Matrix<n> & m1);

// (external instantiation)


GL0::Matrix<3> &
robust_multiply (GL0::Matrix<3> &, const GL0::Matrix<3> &);

GL0::Matrix<4> &
robust_multiply (GL0::Matrix<4> &, const GL0::Matrix<4> &);

N = {3,4}Matrix.cc中有一个operator *=实现,但它依赖于天真的内部产品,并且不健壮--尽管通常足以用于GL /可视化。robust_multiply函数也在Matrix.cc中实现。

当然,我需要Matrix乘法运算符:

代码语言:javascript
复制
template <int n> GL0::Matrix<n>
operator * (GL0::Matrix<n> m0, const GL0::Matrix<n> & m1) {
    return (m0 *= m1);
}

向我介绍了有问题的定义:

代码语言:javascript
复制
inline GL0::Matrix<3>
robust_multiply (GL0::Matrix<3> m0, const GL0::Matrix<3> & m1) {
    return robust_multiply(m0, m1);
}

inline GL0::Matrix<4>
robust_multiply (GL0::Matrix<4> m0, const GL0::Matrix<4> & m1) {
    return robust_multiply(m0, m1);
}

robust_multiply(m0, m1)的调用是不明确的。Q:我如何强迫LHS参数被解释为引用,以确保调用以前修改(m0)参数的函数。显然可以将robust_multiply命名为其他东西,但我更感兴趣的是使用类型系统。我觉得我错过了<utility><functional>中一些显而易见的东西。如何强制调用正确的函数?

(关于“数”这个词,我很抱歉--我在写作时试图澄清我自己的想法。)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-13 16:04:43

你给robust_multiply取错名字了。

*=*是根本不同的操作。它们是相关的,但不是相同的操作--不同的动词。

当您对不同的名词执行相同的操作时,应使用重载。

如果你这样做,那么你的问题几乎肯定会消失。合理的过载很容易写。

在您的情况下,您希望在写入参数之间进行更改,或者不根据参数的l/r值类别进行更改。这会导致歧义问题。

我的意思是,有一些解决问题的方法--比如使用std::ref或指针,或者使用&&&const&重载--但它们都是补丁。

在编程中给它命名是很困难的。这是一个案例,如果你应该这么努力的话。

..。

现在你能做的一件事就是祝福这些争论。

代码语言:javascript
复制
template<class T>
struct robust{
  T t;
  explicit operator T&()&{return t;}
  explicit operator T()&&{
    return std::forward<T>(t);
  }
  // also get() methods
  explicit robust(T&&tin):
    t(std::forward<T>(tin))
  {}
};

然后为健壮的包装矩阵重写*=*

代码语言:javascript
复制
robust{a}*=b;

( lhs必须保持稳健,以降低过载计数)。

现在动词清楚了,我只是把名词修饰一下。

但这只是一个想法,而不是使用测试。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71458432

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档