std::cout是 的一个实例std::ostream。std::cout我可以在名为 的文件中看到 的声明/usr/include/c++/7/iostream:
extern ostream cout; /// Linked to standard output
Run Code Online (Sandbox Code Playgroud)
并且std::ostream由 定义typedef std::basic_ostream<char> std::ostream。
更重要的是,您似乎无法创建 的实例std::ostream。请参阅此演示代码片段:
#include<iostream>
int main()
{
std::ostream os;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
以下是编译器对上面代码片段的抱怨:
In file included from /opt/compiler-explorer/gcc-4.9.0/include/c++/4.9.0/iostream:39:0,
from <source>:1:
/opt/compiler-explorer/gcc-4.9.0/include/c++/4.9.0/ostream: In function 'int main()':
/opt/compiler-explorer/gcc-4.9.0/include/c++/4.9.0/ostream:384:7: error: 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char; _Traits = std::char_traits<char>]' is protected
basic_ostream()
^
<source>:5:18: error: within this context
std::ostream os;
^
Run Code Online (Sandbox Code Playgroud)
问题来了,既然被std::basic_ostream<_CharT, …
string::c_str()调用时实际上做了什么?
string::c_str()将分配内存,复制字符串对象的内部数据并将空终止字符附加到新分配的内存中?或者
string::c_str()分配内存并复制过来。string实际上,始终存在空终止符是唯一合理的实现。在这个问题的答案的评论中有人说C++11 要求为尾随std::string分配额外的char'\0'. 所以看来第二种选择是可能的。
另一个人说,std::string操作——例如迭代、串联和元素变异——不需要零终止符。除非您将 传递string给需要以零结尾的字符串的函数,否则可以省略它。
更多来自专家的声音:
为什么实现者通常让 .data() 和 .c_str() 做同样的事情?
因为这样做效率更高。使 .data() 返回非 null 终止的内容的唯一方法是让 .c_str() 或 .data() 复制其内部缓冲区,或者仅使用 2 个缓冲区。拥有一个以 null 结尾的缓冲区始终意味着您在实现 std::string 时始终可以仅使用一个内部缓冲区。
string::c_str()所以我现在真的很困惑,调用时实际上做了什么?
更新:
如果c_str()实现为简单地返回指针,则它已经被分配和管理。
A。由于c_str()必须以 null 终止,因此内部缓冲区需要始终以 null 终止,即使对于空的 std::string,例如: ;的内部存储器中std::string demo_str应该有一个。我对吗?\0demo_str
B.std::string::substr()调用时会发生什么自动将 a …
下面列出了相关代码,您可以在https://godbolt.org/z/3GH8zD上查看。我确实可以解决编译器编译错误。但我并不完全清楚其背后的原因。我将不胜感激对这个问题有一些帮助。
struct A
{
int x;
A(int x = 1): x(x) {} // user-defined default constructor
};
struct F : public A
{
int& ref; // reference member
const int c; // const member
// F::F() is implicitly defined as deleted
};
int main()
{
F f; // compile error
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
Could not execute the program
Compiler returned: 1
Compiler stderr
<source>:10:15: error: declaration does not declare anything [-fpermissive]
10 | const int; // const member
| ^~~ …Run Code Online (Sandbox Code Playgroud) 根据这个文档,它说(强调我的):
http://www.cplusplus.com/reference/memory/shared_ptr/owner_before/
与 operator< 重载不同,这种排序考虑了shared_ptr 拥有的指针,而不是存储的指针,如果这些对象中的两个被认为是等价的(即,无论操作数的顺序如何,此函数都返回 false),如果它们两者共享所有权,或者它们都为空,即使它们存储的指针值不同。
所述存储的指针(即,指针的shared_ptr对象解除引用到)可能不是在所有的指针(即,指针上物件破坏删除)如果对象的shared_ptr是一个别名(别名构造的对象和它们的副本)。
的“拥有的指针”和“存储的指针”有std::shared_ptr什么区别?
我将不胜感激能在这个问题上得到一些帮助。
这是一些相关代码(检查http://cpp.sh/27auqq):
// enable_shared_from_this example
#include <iostream>
#include <memory>
struct C : std::enable_shared_from_this<C> {int a; int b; };
int main () {
std::shared_ptr<C> foo, bar;
foo = std::make_shared<C>();
bar = foo->shared_from_this();
std::shared_ptr<int> p1(foo, &foo->a);
std::shared_ptr<int> p2(foo, &foo->b);
*p1=5;
*p2=9;
std::cout << p1.use_count() << std::endl;
std::cout << foo->a << std::endl;
std::cout << foo->b << std::endl;
if (!foo.owner_before(bar) && !bar.owner_before(foo))
std::cout …Run Code Online (Sandbox Code Playgroud) 调用指向不再存在的 lambda 的指针是否合法?
这是演示代码片段。
#include <iostream>
typedef int (*Func)(int a);
int main()
{
Func fun;
{
auto lambda = [](int a)->int{std::cout << a << std::endl; return a;};
fun =lambda;
}
fun(6); //Is it legal? The variable lambda does not exist anymore.
}
Run Code Online (Sandbox Code Playgroud)
通用条件怎么样,比如说有捕获的 lambda?
我有这样的文件
.
??? CMakeLists.txt
??? src
??? CMakeLists.txt
??? main.c
Run Code Online (Sandbox Code Playgroud)
这是关于这个文件的内容
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
PROJECT (HELLO)
ADD_SUBDIRECTORY(src bin)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/binarydir)
$ cat src/CMakeLists.txt
ADD_EXECUTABLE(hello main.c)
$ cat src/main.c
#include <stdio.h>
int main()
{
printf("Hello World from t1 main().\n");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
然后我使用以下命令构建它
$ mkdir build
$ cd build
$ cmake ..
$ make
Run Code Online (Sandbox Code Playgroud)
这是结果目录结构

然后二进制文件hello将在目录中build/bin作为图片生成,但它应该在,build/binarydir因为我有set的值EXECUTABLE_OUTPUT_PATH,不是吗?我错过了什么?
为什么在这段代码片段中weak.lock()返回nullptr:
std::weak_ptr<int> weakPtr1 = std::make_shared<int>(6);
std::cout << weakPtr1.lock() << std::endl;
Run Code Online (Sandbox Code Playgroud)
而它在以下情况下工作:
std::shared_ptr<int> sharedPtr = std::make_shared<int>(99);
std::weak_ptr<int> weakPtr2 = sharedPtr;
std::cout << weakPtr2.lock() << std::endl;
Run Code Online (Sandbox Code Playgroud)
检查 cpp.sh/9gkys。
我曾经想过,想过,但我现在仍然很困惑。我将不胜感激能在这个问题上得到一些帮助。
将派生类标记为可移动而基类不可移动是否有意义\适合吗?
我知道这种不一致在 C++ 中是合法的,但它在实践中有意义\适合吗?
一般来说,我应该刻意保持这种一致性吗?
这种情况怎么样:当我打算将派生类标记为不可移动和不可复制时,我是否也应该将基类标记为不可移动和不可复制?
我做了几次测试才清楚。
这是第一个例子。由于基类是不可复制和不可移动的,因此派生类实际上是不可移动的,因为它有一个移动构造函数,这在我的期望中。提示:下面的代码片段无法编译。
#include <memory>
#include <string>
#include <iostream>
class Base {
public:
Base(){}
Base(const Base&) = delete;
Base(Base&&) = delete;
Base& operator=(const Base&) = delete;
Base& operator=(Base&&) = delete;
};
class Derived:public Base
{
public:
Derived(){}
Derived(const Derived&) = default;
Derived(Derived&&) = default;
Derived& operator=(const Derived&) = default;
Derived& operator=(Derived&&) = default;
};
int main()
{
Derived derived;
Derived derived1{std::move(derived)};
}
Run Code Online (Sandbox Code Playgroud)
这是第二个例子。基类是可复制且不可移动的,但派生类实际上是可移动的,因为在调用派生类的移动构造函数时,它会调用基类的复制构造函数,而不是基类的移动构造函数,即也在我的预料之中。提示:下面的代码片段效果很好。
#include …Run Code Online (Sandbox Code Playgroud) 如何理解这template<typename Tp> bool is_array<Tp[]> = true是对 的部分专业化template<typename T> bool is_array<Tp> = true?
这是相关的代码片段:
#include<iostream>
template<typename T>
bool is_array = false;
template<typename Tp>
bool is_array<Tp[]> = true;
int main()
{
std::cout << is_array<int> << std::endl;
std::cout << is_array<int[]> << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我还注意到,一般来说,部分模板特化中的模板参数数量少于主模板中的模板参数数量。
部分专业化通常是这样的:
#include<iostream>
template<typename T, typename U>
class add
{
public:
add(T x, U y)
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
template<typename U>
class add<int, U>
{
public:
add(int x, U …Run Code Online (Sandbox Code Playgroud) 实际应用中,有什么情况std::unordered_map必须用 来代替std::map?
我知道它们之间的区别,比如内部实现、搜索元素的时间复杂度等等。
但我实在找不到确实std::unordered_map可以替代的情况std::map。