【问题标题】:How does std::find auto-magically knows the end of an array in C++?std::find 如何自动神奇地知道 C++ 中数组的结尾?
【发布时间】:2014-09-18 16:14:50
【问题描述】:

为什么下面的代码中有一个原子变量? - 因为它是从多个线程更新 m_subscriptions 数组的更大代码库的一部分。请耐心等待我 ..

这是我的问题:

#include <iostream>
#include <atomic>
#include <algorithm>
#include <iterator>


#define MAX_SUBSCRIPTIONS 45

static std::atomic<int> numberOfSubscriptions;

int main ()
{
    int m_subscriptions[MAX_SUBSCRIPTIONS] = {};
    numberOfSubscriptions.fetch_add(0, std::memory_order_relaxed);

    m_subscriptions[numberOfSubscriptions] = 12;
    numberOfSubscriptions.fetch_add(1);
    m_subscriptions[numberOfSubscriptions] = 13;
    numberOfSubscriptions.fetch_add(1);
    m_subscriptions[numberOfSubscriptions] = 14;
    numberOfSubscriptions.fetch_add(1);
    m_subscriptions[numberOfSubscriptions] = 15;
    numberOfSubscriptions.fetch_add(1);
    m_subscriptions[numberOfSubscriptions] = 16;
    numberOfSubscriptions.fetch_add(1);

    for ( int i = 0; i < numberOfSubscriptions; i++ )
        std::cout << m_subscriptions[ i ] << "\t "; 

    std::cout << std::endl;

    auto result = std::find(m_subscriptions, m_subscriptions + numberOfSubscriptions, 44);

    if ( result == std::end(m_subscriptions) )
        std::cout << "Not Found" << std::endl;
    else 
        std::cout << *result << std::endl;
}

当我传递数组中不存在的东西时,不打印“未找到”。

如果我将if ( result == std::end(m_subscriptions) ) 替换为

if ( result == (m_subscriptions + numberOfSubscriptions) ) 有用 !

怎么样??

std::find 是如何知道m_subscriptions 中有多少个值被初始化的?它是否应该一直持续到最后,即 m_subscriptions[MAX_SUBSCRIPTIONS] 就像人们期望一台愚蠢的计算机那样?

换句话说,为什么std::findm_subscriptions + numberOfSubscriptions 处停止搜索44?为什么直到m_subscriptions[MAX_SUBSCRIPTIONS] 才继续?

【问题讨论】:

  • 您使用m_subscriptions, m_subscriptions + numberOfSubscriptions 调用它。你希望它做什么?
  • 这个问题似乎是题外话,因为它是关于标准行为的忽视
  • 这并没有使它偏离主题。这是一个很好的问题,已经得到了回答。

标签: c++ arrays stl standard-library


【解决方案1】:

std::find 不知道数组或其中初始化的元素。你用第二个参数告诉它在哪里停止:

std::find(m_subscriptions, // Start here
          m_subscriptions + numberOfSubscriptions, // Stop here
          44); // Try to find this

如果它没有找到你要找的东西,它只会返回第二个参数,这是你给它的范围的结尾。

如果您将std::end(m_subscriptions) 作为第二个参数传递,它将遍历您尚未分配的所有元素。然而,值得注意的是这些不是未初始化的,它们已经被初始化了。当您使用 {} 进行聚合初始化时,您未指定的聚合的任何成员都将被初始化。无论如何,即使它们未初始化,也无法判断某些内容是否已初始化。

【讨论】:

    【解决方案2】:

    std::find 需要结束迭代器,并指向未找到元素的地方

    m_subscriptions + numberOfSubscriptions 指向添加的最后一个元素

    std::end(m_subscriptions) 指向通过总容量 (45)

    尝试打印这些:

    std::cout  << result - m_subscriptions ; // 5 with search element not in list
    std::cout <<  std::end(m_subscriptions)  - m_subscriptions ; //45
    

    【讨论】:

      猜你喜欢
      • 2016-02-03
      • 2012-04-30
      • 2014-04-03
      • 2012-01-09
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多