为什么要删除vector.end()?

时间:2015-12-22 11:56:08

标签: c++ stl stdvector

今天我做了一些代码,看起来像这样:

vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>));

当上面的代码不应该删除任何内容时,意味着std :: remove_if应该返回vec.end(),当我收到大小减少了1的向量时,我感到非常惊讶:最后一个元素被删除了。通过将上面改为:

来解决问题
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());

但仍有疑问:怎么可以

vec.erase(vec.end());

做任何工作?不应该是未定义的行为吗?

编辑:显然,我对欠定义行为的理解从一开始就是错误的,而我所观察到的一直是UB。谢谢大家回答我的问题。

3 个答案:

答案 0 :(得分:3)

未定义的行为。 特别是,这意味着您可能会看到尺寸减少了一个

More on UB

答案 1 :(得分:1)

  

为什么要删除vector.end()?

不允许。 vector::erase(const_iterator)的参数必须是向量中的有效的可解除引用的迭代器。过去的迭代器是有效的,但不能解除引用。

  

怎么可以做任何工作?不应该是未定义的行为吗?

为什么你认为它不起作用并且是未定义的行为?

您认为未定义的行为意味着什么?

答案 2 :(得分:1)

首先,它不是

var pkgcloud = require('pkgcloud-bluemix-objectstorage');

// Create a config object
    var config = {};

// Specify Openstack as the provider
    config.provider = "openstack";

// Authentication url
    config.authUrl = 'https://identity.open.softlayer.com/';
    config.region= 'dallas';

// Use the service catalog
    config.useServiceCatalog = true;

// true for applications running inside Bluemix, otherwise false
    config.useInternal = false;

// projectId as provided in your Service Credentials
    config.tenantId = 'xxx';

// userId as provided in your Service Credentials
    config.userId = 'xxx';

// username as provided in your Service Credentials
    config.username = 'xxx';

// password as provided in your Service Credentials
    config.password = 'xxx';

// This is part which is NOT in original pkgcloud. This is how it works with newest version of bluemix and pkgcloud at 22.12.2015. 
//In reality, anything you put in this config.auth will be send in body to server, so if you need change anything to make it work, you can. PS : Yes, these are the same credentials as you put to config before. 
//I do not fill this automatically to make it transparent.

    config.auth = {
        tenantId: "xxx", //projectId
        passwordCredentials: {
            userId: "xxx", //userId
            password: "xxx" //password
        }
    };

    console.log("config: " + JSON.stringify(config));

// Create a pkgcloud storage client
    var storageClient = pkgcloud.storage.createClient(config);

// Authenticate to OpenStack
     storageClient.auth(function (error) {
        if (error) {
            console.error("storageClient.auth() : error creating storage client: ", error);
        }
        else {
            // Print the identity object which contains your Keystone token.
            console.log("storageClient.auth() : created storage client: " + JSON.stringify(storageClient._identity));
        }

    });

真的是

vec.erase(std::remove_if(<lambda here>), vec.end());

这与

完全不同
vec.erase(std::remove_if(vec.begin(), vec.end(), <lambda here>), vec.end());

后者vec.erase(vec.end()); 当然是未定义的行为。前者不是。

vec.erase(vec.end())

这将删除向量中与lambda匹配的值,并且 - 最重要的是 - 这将返回新序列的结束值。

std::remove_if(vec.begin(), vec.end(), <lambda here>)

这将从vec.erase(first, last); 迭代器值开始删除向量中的值,first迭代器值中删除但不包括

将两者放在一起,然后从矢量中删除匹配的值,然后相应地缩小矢量。