简体   繁体   English

避免模​​板化运算符重载的隐式参数转换

[英]Avoid implicit argument conversion of templated operator overload

My question was, how the displayed behaviour could be prevented, but as Cheersandhth.-Alf pointed out, I failed to include my constructor which caused this problem.我的问题是,如何防止显示的行为,但正如 Cheersandhth.-Alf 指出的那样,我没有包含导致此问题的构造函数。 The constructor is now included and it is obvious, that forwarding the float (aswell as anything else) to the std::array ctor caused this problem.现在包含构造函数,很明显,将浮点数(以及其他任何内容)转发到 std::array 构造函数会导致此问题。

I would still like to be able to use this kind of initialization Vec2 a = {1.f, 2.f} , but the forwarding ctor is pretty dangerous, so I will avoid that.我仍然希望能够使用这种初始化Vec2 a = {1.f, 2.f} ,但转发 ctor 非常危险,所以我会避免这种情况。

I have a Vec class derived from std::array which is supposed to implement the usual component-wise arithmetic operations via operator overloads.我有一个从 std::array 派生的 Vec 类,它应该通过运算符重载来实现通常的组件式算术运算。 The operators should be implemented both for other Vecs of the same type and size (in that case operating on the corresponding vector components), aswell as integral and floating point types.这些运算符应该为相同类型和大小的其他 Vec 实现(在这种情况下,在相应的向量组件上运行),以及整数和浮点类型。

eg例如

{1.f, 2.f, 3.f} * 2.f = {2.f, 4.f, 6.f}
{1.f, 0.f} + {0.f, 1.f} = {1.f, 1.f}

Here is what I did (only shown for operator*) https://godbolt.org/g/PtCkzR :这是我所做的(仅显示给操作员*) https://godbolt.org/g/PtCkzR

template<class T, size_t N>
class Vec : public std::array<T, N>
{
public:
  template<typename... S>
  Vec(S&&... params) : std::array<T, N>{std::forward<S>(params)...} { };

  friend Vec<T, N>& operator*=(Vec<T, N>& a, const Vec<T, N>& b)
  {
    std::transform(a.begin(), a.end(), b.begin(), a.begin(), std::multiplies<>());
    return a;
  }

  template<class S>
  friend Vec<T, N>& operator*=(Vec<T, N>& a, const S& b)
  {
    std::transform(a.begin(), a.end(), a.begin(), [&] (T x) { return x*b; });
    return a;
  }

  template<class S>
  friend Vec<T, N> operator*(Vec<T, N> a, const S& b)
  {
    return a *= b;
  }
};
using Vec2 = Vec<float, 2>;

Now, when I want to multiply a vector with a float this happens:现在,当我想将一个向量与一个浮点数相乘时,会发生这种情况:

Vec2 a{1.f, 1.f};
auto b = a * 0.5f; // b = {.5f, .5f} <- as expected
auto c = 0.5f * a; // c = {.5f, 0.f} <- what happened here?

This happens because the 0.5f in the third line is implicitly converted to a Vec2 {0.5f, 0.f} and is then passed to the operator*(Vec2, const Vec2&) overload.发生这种情况是因为第三行中的0.5f被隐式转换为 Vec2 {0.5f, 0.f} ,然后传递给operator*(Vec2, const Vec2&)重载。

Add another operator* overload function where the LHS can be a number.添加另一个operator*重载函数,其中 LHS 可以是数字。

template<class S>
   friend Vec<T, N> operator*(S b, Vec<T, N> a)
   {
      return a *= b;
   }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM