【问题标题】:Counting elements in array template计算数组模板中的元素
【发布时间】:2020-07-27 08:43:38
【问题描述】:

我为二维数组编写了一个模板,并设计了一种计算数组中有多少元素的方法。但是,该方法不返回任何内容。

template <class T, int row, int column>
class array2d {
private:
    typedef T value;
    //typedef value * iterator;
    std::vector<T> array;
public:

    array2d() : array(row * column) {}
    explicit array2d( std::initializer_list<T> list) : array(list) {}

    constexpr T& length(){
        int cnt = 0;

        for (auto element : array)
            ++cnt;

        return cnt;
    }

其他方法正确返回我需要的内容。似乎使用 int 时,我不能使用 .size(),因为它返回 unsigned long long int 并决定计算 for 中的元素。

【问题讨论】:

  • 未定义的行为!您正在返回对局部变量 cnt 的引用。删除参考。也不要过于复杂,只需使用arrat.size()
  • 不要返回对本地的引用 - 按值返回。另外,为什么array2d&lt;double&gt; 的长度会是double 类型?不应该是整数类型吗?为什么不直接返回row *columnarray.size()
  • 元素个数不是静态已知的吗? row * column?如果你有静态数组,为什么要使用std::vector。为什么不std::array&lt;std::array, column&gt;, row&gt;
  • 另外,你用 int 计数但返回 T。而且你已经有了 array.size() 那么为什么要迭代向量呢?
  • 顺便说一句,您应该包含一个完整的示例,用于询问有关代码问题的问题 (minimal reproducible example)。该函数确实返回了一些东西,而不是你期望它返回的东西

标签: c++ arrays templates


【解决方案1】:

T&amp; 是一个非常糟糕的返回类型选择。您通过返回对本地对象的引用获得 UB,如果我将您的 array2ddouble 类型一起使用怎么办?我可以将array2d 与非算术类型一起使用吗?

改为返回std::size_t

std::size_t length(){
    return array.size();
}

【讨论】:

  • 我使用了 T& 因为这是作者在 this book 中使用的。他定义了大多数方法,例如constexpr T const &amp; operator() (size_t const r, size_t const c) const { return arr[r*column + c]; }
  • @xampierre 访问数组元素是有意义的,因为它们是T 类型,并且引用授予对实际元素的访问权限,而不是副本。但是对于size()...假设我使用您的课程并拥有array2d&lt;double&gt; myArray;。如果我要求myArray.length() 并得到24.99 作为回报,您认为是否正确?关于按引用返回,这仅在对象超过引用时才有意义。在实践中,它几乎只在返回类或参数的成员时完成(如在operator&lt;&lt; 中)。在这里你要返回一个局部变量,而不是一个类成员。
【解决方案2】:

没有理由不使用size()。首选类型是 std::size_t,但您可以选择最适合您的类型:

auto length()
{
  return (your_type_t) array.size();
}

【讨论】:

  • 只有代码的答案不好。你能解释一下为什么这是正确的或 OPs 代码有什么问题吗?
  • 你错过了解释为什么 OPs 代码是错误的,所以不清楚你的代码是如何“更好”的。问题不在于size()
  • OPs 代码无法编译。由于它是UB,它还可能爆炸计算机。
  • 我似乎看不到 OP 试图达到的总体方向。这个问题需要用一个可重复的例子来澄清。
  • OPs 代码中的 UB 是什么?如果您指的是返回参考,那么那不是UB。仅使用参考即可,所以是的,我完全同意没有完整示例就无法回答所写的问题
猜你喜欢
  • 1970-01-01
  • 2016-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 2021-07-18
  • 2021-10-10
  • 1970-01-01
相关资源
最近更新 更多