struct A{};
template <typename T>
struct B
{
typename ::A a1; //(1)
typename A a2; //(2): error
};
int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)
为什么第一种情况是正确的,但第二种情况不正确?我不明白这种限制的含义.
无论如何,为什么第一个案例被允许?::A不是模板参数相关的名称.这有什么意义?
我已经在标准(n4296),23.2.3/4(表100)中看到了对序列stl容器的要求,并且读过一个带有参数迭代器的构造函数(X - 容器,i和j - 输入迭代器)
X(i, j)
X a(i, j)
Run Code Online (Sandbox Code Playgroud)
要求容器的元素类型为EmplaceConstructible.
Requires: T shall be EmplaceConstructible into X from *i
Run Code Online (Sandbox Code Playgroud)
我认为构造函数可以通过为范围中的每个迭代器调用std :: allocator_traits :: construct(m,p,*it)方法来实现(其中m - 类型A的分配器,p - 指向内存的指针,它 - 迭代器in [i; j],并且只需要CopyInsertable元素的概念,因为只提供一个参数用于复制/移动,而EmplaceConstructible概念要求元素由一组参数构造.这个决定有什么理由吗?
我已经看到有关该方法的 cppreference 的以下注释valueless_by_exception:
在以下情况下,变体可能变得毫无价值:
- (保证)在移动分配期间对包含的值进行移动初始化期间抛出异常
- (可选)在复制分配期间对包含的值进行复制初始化期间抛出异常
所以,像这样的代码
std::variant<MyClass> var = {...};
var = myClassObj;
Run Code Online (Sandbox Code Playgroud)
不需要使var.valueless_by_exception()等于 true (并且大概会保留var之前的状态),但是这段代码
std::variant<MyClass> var = {...};
var = std::move(myClassObj);
Run Code Online (Sandbox Code Playgroud)
var.valueless_by_exception()如果发生异常,保证等于true。
复制和移动分配之间的规格差异的实际原因是什么?
我不明白,为什么在最坏的情况下(其中 N 是元素数)有std::unordered_set O(N) 复杂度的擦除方法?标准 (n4296) 说明了所有三个版本的擦除方法在最坏情况下的复杂度为 O(a.size())(a是容器),并且仅使指向已擦除元素的迭代器无效,而不是所有迭代器(即重新散列不t 发生)。即使对于采用一个迭代器参数并且在平均情况下具有恒定复杂性的版本也是如此。我想是因为那抹version 返回一个迭代器到下一个元素,这需要找到擦除元素后的第一个非空桶,它给出了 O(a.bucket_count()) 复杂度,但不是 O(a.size())!元素的数量与桶的数量不成正比。例如:
#include <iostream>
#include <unordered_set>
using namespace std;
int main()
{
std::unordered_set<int> aSet;
aSet.insert ({125, 126});
aSet.rehash (1000);
cout << aSet.size() << endl;
cout << aSet.bucket_count() << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出是
Size: 2
Bucket count: 1031
Run Code Online (Sandbox Code Playgroud)
一个容器的大小只有2,bucket_count是1031。当erase方法被调用时,它会寻找下一个非空的bucket,可以放在最后,即复杂度是O(a.bucket_count()),但是不是 O(a.size())。标准给出 O(a.size()) 复杂度的原因是什么?
struct CL
{
int i;
void fnc()
{
[&this](){i=1;}; // (1) error
[&](){i=1;}; // (2) ok
}
};
Run Code Online (Sandbox Code Playgroud)
这是第1个不起作用的情况,但是第2个案件.这是为什么?
我看到标准5.1.2/1:
捕获:
标识符
&标识符
此
(即&不存在)
和5.1.2/15:
如果实体是隐式或显式捕获但未通过复制捕获,则通过引用捕获实体
在第二种情况下,根据5.1.2/14,副本没有捕获"这个":
如果隐式捕获实体,并且capture-default为=,或者如果使用不包含&的捕获显式捕获实体,则通过副本捕获实体
但是如何明确地按值捕获"this"指针?或者只能隐式使用default-capture&?
我可以为一维数组编写operator new,如下所示:
int n{3};
new int[n];
Run Code Online (Sandbox Code Playgroud)
它至少分配sizeof(int) * n字节。但是当我想创建二维或多维数组时,只有第一维可能是非常量:
int n{3};
new int[n][3]; //ok
new int[n][n]; //error;
Run Code Online (Sandbox Code Playgroud)
为什么会出现这样的限制?确定至少需要sizeof(int) * n * n分配字节数是否有任何困难?