今天我做了一些代码,看起来像这样:
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。谢谢大家回答我的问题。
答案 0 :(得分:3)
是未定义的行为。 特别是,这意味着您可能会看到尺寸减少了一个
答案 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
迭代器值中删除但不包括。
将两者放在一起,然后从矢量中删除匹配的值,然后相应地缩小矢量。