【问题标题】:Implicit typecasting not working for template class隐式类型转换不适用于模板类
【发布时间】:2020-04-06 14:04:23
【问题描述】:

我有两个结构,A 和 B,因此可以将 B 转换为 A,并且我为 A 定义了 operator+

struct A
{
  float x;
  A(float _x) : x(_x) {}
};

struct B
{
  float x;
  operator A()
  {
    return A{x};
  }
};

A operator+ (A left, A right)
{
  return A(left.x+right.x);
}

如果不为 B 定义 operator+,编译器就知道将 B 对象隐式转换为 A,然后添加它们。这意味着以下作品 B b1 = {1.0f}; B b2 = {2.0f}; A a = b1 + b2

但是,当我将结构转换为模板类并尝试在 Ds 而不是 Bs 上执行相同的操作时,我收到错误:

错误:'operator+' 不匹配(操作数类型为 'D' 和 'D')

template<typename T>
struct C
{
  T x;
  C<T>(T _x) : x(_x) {}
};

template<typename T>
struct D
{
  T x;
  operator C<T>()
  {
    return C<T>(x);
  }
};

template<typename T>
C<T> operator+ (C<T> left, C<T> right)
{
  return C<T>(left.x+right.x);
}

为什么将我的结构转换为模板会导致隐式转换停止工作?

【问题讨论】:

  • 我敢打赌,你可以在这里删除 90% 的代码,但仍然会出现问题。使用更少的代码,您可能会看到自己的解决方案。
  • 您为 A 定义了 operator+,但没有为 B<..> 定义。
  • xy 和 yx 属于 B 类,您没有为 B 类定义运算符 +
  • @Pete Becker 我已经简化了代码,但我仍然没有看到解决方案。我认为我原来的帖子很不清楚我在问什么,所以希望现在更清楚了。
  • @Gupta 我试图表明您并不总是需要为 B 类定义运算符。我意识到我最初的问题并不清楚,所以我对其进行了编辑。

标签: c++ templates operator-overloading


【解决方案1】:

问题是你的操作符是模板,所以要匹配它的参数,隐式转换不能用于推导。

friend是你的朋友:)

template<typename T>
struct C
{
  T x;
  C(T _x) : x(_x) {}

  friend C operator+ (C left, C right) // Function is no longer template
  {
      return C(left.x + right.x);
  }
};

现在,您可以使用c + cc + dd + c

友元函数对 ADL 有特殊的规则,所以对于d + d,我们不看friend operator+(C,C)

所以我们需要D 中的另一个friend 函数:

template <typename T>
struct D
{
  T x;
  operator C<T>() { return C<T>(x); }

  friend C<T> operator+ (D left, D right)
  {
    return C<T>(left) + C<T>(right);
  }
};

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-23
    相关资源
    最近更新 更多