假设我有一个函数,根据某些运行时条件创建昂贵的自动对象或创建便宜的自动对象:
void foo() {
if (runtimeCondition) {
int x = 0;
} else {
SuperLargeObject y;
}
}
Run Code Online (Sandbox Code Playgroud)
当编译器为此函数的堆栈帧分配内存时,它是否会分配足够的内存来存储SuperLargeObject,并且如果导致 的条件为int真,则额外的内存将不会被使用?或者它会以其他方式分配内存吗?
我问是因为auto推断{}是initializer_list。我不知道核心语言像这样依赖标准库中的任何其他类。你可以去掉vectoror array,C++ 仍然可以运行,但是去掉initializer_list它就会崩溃。
std::allocatorC++ 中的默认类是无状态的。这意味着任何实例都std::allocator可以释放另一个实例分配的内存std::allocator。那么使用分配器实例来分配内存有什么意义呢?
例如,为什么内存分配是这样的:
allocator<T> alloc, alloc2;
T* buffer = alloc.allocate(42);
alloc2.deallocate(buffer);
Run Code Online (Sandbox Code Playgroud)
当函数可以轻松完成相同的工作时:
T* buffer = allocate(42);
deallocate(buffer);
Run Code Online (Sandbox Code Playgroud) 采取这个代码:
std::condition_variable var;
var.wait(lock, [&sharedBool] { return sharedBool; });
Run Code Online (Sandbox Code Playgroud)
当var从sharedBool读取时,线程安全吗?如果不是,那么这样做sharedBool合理std::atomic<bool>吗?
参加这堂课:
class Foo {
public:
using MyType = Foo;
MyType* m = nullptr; //ok
MyType* functor() { //ok
return nullptr;
}
MyType() = default; //error
~MyType() = default; //error
};
Run Code Online (Sandbox Code Playgroud)
为什么可以对成员使用别名,但不能对构造函数或析构函数使用别名?
假设我有以下内容tuple:
std::tuple<int, int, int> setVals(int val)
{
return std::make_tuple(val, val, val);
}
Run Code Online (Sandbox Code Playgroud)
拥有这样的结构化绑定真的很好:auto [x, y, z] = setVals(42);
是否可以有某种可变参数签名setVals,以便我可以使用任意数量的变量进行结构化绑定?例如,auto [x, y] = setVals(42);或者auto [x, y, z, x2, y2, z2] = setVals(42);
我知道我可以使用可变参数函数模板,在其中我可以声明一些整数并将它们作为引用传递,但是结构化绑定非常方便,我想知道我刚刚展示的东西是否可能。如果这个问题问得不好,我很抱歉。
为什么这有效:
char foo[6] = "shock";`
Run Code Online (Sandbox Code Playgroud)
虽然这不起作用:
char* bar = "shock"; //error
Run Code Online (Sandbox Code Playgroud)
为什么bar必须是const而foo不是?fooC 中的数组衰减为指针,因此技术上和不bar具有相同的类型吗?
如果这是一个非常菜鸟的问题,我很抱歉,但我对如何指定 std::function 参数列表感到困惑,如下所示:
std::function<void(double)> func;
Run Code Online (Sandbox Code Playgroud)
但在实际的函数中,这是行不通的:
void passFunc(void(double) func) {}
Run Code Online (Sandbox Code Playgroud)
对于上面的方法,您必须指定一个函数指针。那么如何允许 void(double) 传递到 std::function 中?void(double) 是一种类型吗?如果不是,它怎么会出现在 std::function 的参数列表中?如果它是类型,为什么 void(double) 作为函数参数的类型是无效的?
我理解为什么 stl 索引是无符号的,因为你永远不会有负索引。但对于普通的 C 数组,索引是有符号的。为什么是这样?
如果有充分的理由对 C 数组索引进行签名,那么为什么他们决定使 stl 索引不同呢?
我在查看时遇到了这个例子std::enable_if:
template<class T,
typename = std::enable_if_t<std::is_array<T>::value> >
void destroy(T* t)
{
for(std::size_t i = 0; i < std::extent<T>::value; ++i) {
destroy((*t)[i]);
}
}
Run Code Online (Sandbox Code Playgroud)
在模板参数列表中,您可以放置非模板化的类/结构。所以当我们删除typename =. 这段代码中的 是什么typename =意思和作用?
在 C++ 中,您可以创建检查特定类型相等性的概念:
template<typename T> concept Int = std::is_same_v<T, int>;
template<typename T> concept String = std::is_same_v<T, std::string>;
Run Code Online (Sandbox Code Playgroud)
是否可以创建一个检查任何类型的类型相等性的概念,以便我可以使模板看起来像这样:
template<ValidType<int>... Ints> void passInts(Ints... ints) {}
template<ValidType<std::string>... Strings> void passStrings(Strings... strings) {}
Run Code Online (Sandbox Code Playgroud)
这样我只需要编写一个概念来检查类型相等性。我知道我可以用conjunction这个,但我认为概念更清晰。
首先,std::nullptr_t是核心语言类型,那么为什么它在std命名空间中呢?你没有看到std::char或std::int。
其次,它在std命名空间中的什么位置?当我在 Visual Studio 中右键单击以查看其声明位置时,它显示“符号 nullptr_t 未位于任何源文件中”。如果std::nullptr_t没有在std命名空间中声明,为什么包含的代码std::nullptr_t编译?
编辑: 微软网站上的此链接说 nullptr 是内置类型,并且内置类型未在头文件中定义。
C 数组允许负索引,但我想不出它的用途,因为你永远不会在负索引处有元素。
当然,你可以这样做:
struct Foo {
int arr1[3] = { 1, 2, 3 };
int arr2[3] = { 4, 5, 6 };
};
int main() {
Foo foo;
std::cout << foo.arr2[-2] << std::endl; //output is 2
}
Run Code Online (Sandbox Code Playgroud)
但你为什么想做这样的事情呢?无论如何,什么时候需要对数组进行负索引,以及您会在哪些域中执行此操作?
c++ ×13
templates ×3
arrays ×2
c ×2
pointers ×2
alias ×1
allocator ×1
c++-concepts ×1
enable-if ×1
indexing ×1
memory ×1
stack-frame ×1
std-function ×1
stl ×1