【问题标题】:Issues with c++ cast overloading operatorc++ 强制转换重载运算符的问题
【发布时间】:2014-08-03 05:10:38
【问题描述】:

我有一个模板类,它上面定义了一个强制转换运算符。当我为 operator+ 定义独立重载时,这似乎没有按预期工作。

template <class TT>
class Mtx
{
private:
    MtxView<TT> m_view;
public:
    operator const MtxView<TT> &() const { return m_view; }
    operator MtxView<TT>() { return m_view; }
    ...
};

template <class TT> Mtx<TT> operator+(const MtxView<TT> &m1, const MtxView<TT> &m2) 
{...}

在下面的测试代码中,使用“+”时出现编译错误,即“二进制表达式的操作数无效”。我原以为演员会允许这个工作。为什么会失败,我该如何解决(不从 MtxView 继承)?

Mtx<float> m1, m2, m3;
...
m1 = m2 + m3;

【问题讨论】:

  • 您是否在 Mtx 类中为 operator= 定义了一个重载以获取 MtxView 类型的参数(假设 operator+ 返回一个 MtxView)?
  • 如上所述,operator+ 返回 Mtx 而不是 MtxView
  • 您的 operator+ 是一个模板。推导参数类型时,函数模板需要完全匹配。从不考虑用户定义的转化。

标签: c++ templates casting operator-overloading


【解决方案1】:

g++ 提供更好的错误消息(OT:可能是第一次有人这么说)

e.cc:22:10: note: candidate is:
e.cc:16:29: note: template<class TT> Mtx<TT> operator+(const MtxView<TT>&, const MtxView<TT>&)
     template <class TT> Mtx<TT> operator+(const MtxView<TT> &m1, const MtxView<TT> &m2)
                         ^
e.cc:16:29: note:   template argument deduction/substitution failed:
e.cc:22:12: note:   'Mtx<float>' is not derived from 'const MtxView<TT>'

m1 = m2 + m3;
          ^    

因为14.8.1/6导致模板扣减失败:

如果参数类型不包含参与模板参数推导的模板参数,则将对函数参数执行隐式转换(第 4 条)以将其转换为相应函数参数的类型

用简单的语言,这表示在对函数模板 template&lt;typename TT&gt; U operator+( 执行参数 TT 的推导时不考虑隐式转换运算符...

所以编译器无法推断TT应该是什么类型。

MM's solution(现已删除)有效,因为operator+ 没有函数模板; TT 是已知的,因为您正在调用 Mtx&lt;float&gt; 的成员函数。

【讨论】:

  • +1 我无法像您的解释那样清楚。他需要为这些类型显式声明运算符。
  • 好的,这很好。实际上,我只是在没有模板的版本上对其进行了测试,并且编译正常。
  • 但是,这样做的全部目的是为了避免在 Mtx 或 MtxView 上添加运算符,原因有很多。
  • 可能有一种设计模式可以解决此问题,而无需明确列出您将要使用的每种类型
  • MtxView 可以成为Mtx 的公共基础 .. 或者你也可以定义template &lt;class TT&gt; Mtx&lt;TT&gt; operator+(const Mtx&lt;TT&gt; &amp;m1, const Mtx&lt;TT&gt; &amp;m2) ,它可以显式调用另一个operator+
猜你喜欢
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 2012-12-27
  • 2023-03-22
  • 1970-01-01
相关资源
最近更新 更多