【问题标题】:How to add arithmetic operators to std::array?如何将算术运算符添加到 std::array?
【发布时间】:2019-05-12 00:36:53
【问题描述】:

我希望继承所有的方法,包括std::array的构造函数。我试试

template<class T, size_t N>
class Vec : public array<T, N>
{
public:
    using array<T, N>::array;

    Vec operator+(Vec const& rhs) const
    {
        Vec res;
        transform(begin(), end(), rhs.begin(), res.begin(), plus);
        return res;
    }

};

但是出现了一些编译错误。

  1. 'begin':找不到匹配的重载函数
  2. 我不能像 std 数组那样做 Vec&lt;int, 2&gt; v{1, 2};,即使构造函数是继承的。

我可能会误解一些东西。如何解决这些错误。在 std::array 上添加算术运算符的任何更好的想法。谢谢!

【问题讨论】:

  • 首先你有一个错字(res 应该是 rhs),第二个 std::plus 是一个类型,transform 需要 该类型的一个实例,第三个你需要使用这个-> 在开始和结束之前(我认为是关于两阶段查找的东西?)。第四,Lightness所说的。删除 using array::array 来修复大括号初始化(我不知道为什么,但我认为这与没有用户定义 ctor 的数组有关?)...I think it works now?
  • 如果这是 minimal reproducible example 肯定会很棒,因此任何想要复制/粘贴它的人都不需要提供所有其他内容。
  • 小心stackoverflow.com/questions/2034916/… 我认为它还不适用,但我总是使用 has-a container 而不是 is-a container,以防有人试图扩展类。跨度>

标签: c++ c++11 c++14 c++17 stdarray


【解决方案1】:

好吧,等一下,原因很复杂,但不要害怕,解决方案很简单。继续阅读。

array 是一个模板,所以 array&lt;T, N&gt; 类的成员在模板实例化之前是未知的(记住模板可以被特化)。并且因为begin 似乎不依赖于任何模板参数,它的名称在第一阶段查找时被解析,在array&lt;T, N&gt; 的实例化之前,即在array&lt;T, N&gt; 的成员已知之前。这就是为什么您会收到 begin not found 或类似错误。

简单的解决方案是使用this-&gt;begin。这样begin 将在第二阶段查找时被解析(在std::array&lt;T, N&gt; 被实例化之后),因为现在很明显begin 可以是继承模板类的成员。

另外,plus 在 C++17 中应该是 plus&lt;&gt;{}plus{}

还有一个建议:尽量避免using namespace stdWhy is "using namespace std" considered bad practice?

Two phase lookup - explanation needed

【讨论】:

  • 谢谢,我仍然想知道为什么不能使用聚合初始化Vec&lt;int, 2&gt; v{1, 2};。我正在使用 VS2017。
  • 我在我的命名空间中使用命名空间 std。不确定这是否可以或仍然是不好的做法。
  • @user1899020 因为Vec 不是聚合
  • stackoverflow.com/questions/24280521/… 在使用命名空间std这个话题上,模板还是得放在头文件里吧?因此,这不仅限于您的编译单元。您正在强迫使用它的每个人将所有 std 放在他们的名称空间中。或者你可以写几次“std::”,这似乎是一个合理的负担。
【解决方案2】:

如果您只需要为 std::array 添加算术运算,我认为您不需要为此创建一个类。您可以只定义非成员模板运算符,无需直接访问 std::array 实现即可工作。

template <typename T, size_t N>
auto operator+(const array<T, N>& ob1, const array<T, N>& ob2)->array<T, N> {
    array<T, N> res;
    for (int i = 0; i < N; ++i)
        res[i] = ob1[i] + ob2[i];
    return res; 
}

其他算术运算等等。

【讨论】:

猜你喜欢
  • 2019-12-06
  • 2021-10-25
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多