有人告诉我,以下代码在 C++20 之前具有未定义的行为:
int *p = (int*)malloc(sizeof(int));
*p = 10;
Run Code Online (Sandbox Code Playgroud)
真的吗?
论点是int对象的生命周期在为其分配值之前没有开始(P0593R6)。要解决此问题,new应使用放置:
int *p = (int*)malloc(sizeof(int));
new (p) int;
*p = 10;
Run Code Online (Sandbox Code Playgroud)
我们真的必须调用一个微不足道的默认构造函数来启动对象的生命周期吗?
同时,代码在纯 C 中没有未定义的行为。但是,如果我int在 C 代码中分配 an并在 C++ 代码中使用它呢?
// C source code:
int *alloc_int(void)
{
int *p = (int*)malloc(sizeof(int));
*p = 10;
return p;
}
// C++ source code:
extern "C" int *alloc_int(void);
auto p = alloc_int();
*p = 20;
Run Code Online (Sandbox Code Playgroud)
它仍然是未定义的行为吗?
#include <iostream>
struct uct
{
uct() { std::cerr << "default" << std::endl; }
uct(const uct &) { std::cerr << "copy" << std::endl; }
uct( uct&&) { std::cerr << "move" << std::endl; }
uct(const int &) { std::cerr << "int" << std::endl; }
uct( int &&) { std::cerr << "int" << std::endl; }
template <typename T>
uct(T &&) { std::cerr << "template" << std::endl; }
};
int main()
{
uct u1 ; // default
uct u2( 5); // int
uct u3(u1); …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor constructor-overloading function-templates overload-resolution
问题是关于自我分配。例如,将向量复制到自身中:
std::vector<std::string> vec(5, "hello");
vec = vec;
Run Code Online (Sandbox Code Playgroud)
上面的代码应该对字符串执行5个字符串赋值操作,还是什么都不做?我的意思是以下检查是否有效:
std::vector operator=(const std::vector &rhs)
{
if (this == &rhs)
{ return *this; }
...
}
Run Code Online (Sandbox Code Playgroud)
我正在研究自己的std::variant类实现(只是为了好玩),并且对我是否应该在自赋值运算符的开头添加自赋值检查感兴趣,还是应该将包含的元素复制到自身中?
我了解这通常并不重要。您不应创建利用复制事实的类。但是我很感兴趣该标准是否对此有所说明。
返回对此对象的引用通常用于赋值运算符重载.它还用作命名参数idiom的基础,它允许通过对setter方法的调用链初始化对象:Params().SetX(1).SetY(1)每个都返回对*this的引用.
但是返回引用是否正确*this.如果我们调用该方法为临时对象返回对此的引用,该怎么办:
#include <iostream>
class Obj
{
public:
Obj(int n): member(n) {}
Obj& Me() { return *this; }
int member;
};
Obj MakeObj(int n)
{
return Obj(n);
}
int main()
{
// Are the following constructions are correct:
std::cout << MakeObj(1).Me().member << std::endl;
std::cout << Obj(2).Me().member << std::endl;
Obj(3).Me() = Obj(4);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 从析构函数抛出异常的主要问题是,在析构函数被调用的那一刻,另一个异常可能是"在飞行中"(std::uncaught_exception() == true),因此在这种情况下做什么并不明显.用新的"覆盖"旧的异常将是处理这种情况的可能方法之一.但是决定在这种情况下必须调用std::terminate(或其他std::terminate_handler).
C++ 11通过std::nested_exception类引入了嵌套异常功能.该特征可用于解决上述问题.旧(未捕获)异常可能只是嵌套到新异常中(反之亦然?)然后可能抛出嵌套异常.但是没有使用这个想法.std::terminate在C++ 11和C++ 14中仍然会出现这种情况.
所以问题.是否考虑过嵌套异常的想法?它有什么问题吗?是不是在C++ 17中会改变这种情况?
起初我认为它可以用于性能测量.但它说这std::chrono::high_resolution_clock可能是不稳定(is_steady可能false).据说std::chrono::high_resolution_clock甚至可能是别名std::chrono::system_clock通常不稳定.所以我无法用这种类型的时钟来测量时间间隔,因为在任何时刻都可以调整时钟并且我的测量结果是错误的.
同时我无法将时间点转换std::chrono::high_resolution_clock为日历时间,因为它没有to_time_t方法.所以我也无法用这种类型的时钟获得实时.
那可以std::chrono::high_resolution_clock用什么呢?
template <typename T>
struct A
{
static constexpr T obj {};
static constexpr bool noexcept_copy = noexcept( T{obj} );
static void UsesCopy() { T{obj}; }
static constexpr int C = 1;
};
struct NoCopy
{
constexpr NoCopy() = default;
NoCopy(const NoCopy&) = delete;
};
int main()
{
return A<NoCopy>::C;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码已由GCC成功编译,但是Clang给出了编译错误:
tmp.cpp:6:57: error: call to deleted constructor of 'NoCopy'
static constexpr bool noexcept_copy = noexcept( T{obj} );
^~~~~~
tmp.cpp:20:16: note: in instantiation of template class 'A<NoCopy>' requested here
return A<NoCopy>::C; …Run Code Online (Sandbox Code Playgroud) 以下是声明nullptr_t中<cstddef>:
namespace std {
typedef decltype(nullptr) nullptr_t;
}
Run Code Online (Sandbox Code Playgroud)
根据这个,std::nullptr_t是一个未指定的基本类型的别名nullptr是一个实例.所以实际的类型nullptr没有名称(好吧,语言不给它起名,名称由标准库给出).
nullptr本身就是一个关键字.但标准没有为类型引入关键字nullptr.而是使用decltype(nullptr)提供.
这样做的原因是什么?我觉得很困惑.您需要包含标头并指定std::仅使用语言内置功能.
这是为了保持C++关键字的集合尽可能小吗?这是专门为nullptr委员会或委员会宣布这样的所有新类型,所以namespace std { typedef decltype(false) bool; }如果早些时候作出这样的决定我们会有吗?
这是我的 Makefile:
.PHONY: test%
test1:
# jobserver is UNavailable
make -C sub
test2:
# jobserver is available, ok
+make -C sub
test3:
# jobserver is available, ok
$(MAKE) -C sub
test4:
# jobserver is available, ok
+$(MAKE) -C sub
Run Code Online (Sandbox Code Playgroud)
sub 是包含另一个Makefile(子make)的子目录。
当我运行test1规则时:
$ make -j8 test1
make -C sub
make[1]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
Run Code Online (Sandbox Code Playgroud)
我收到警告说 jobserver 不可用并且sub/Makefile确实在单线程中运行(就像-j1)。
他们说我应该添加+,所以我运行了一个test2包含+beforemake命令的目标。现在我没有看到警告并且sub/Makefile …
下面的代码:
int i = 1;
const int i_c = 2;
volatile int i_v = 3;
const volatile int i_cv = 4;
typedef std::variant<int, const int, volatile int, const volatile int> TVariant;
TVariant var (i );
TVariant var_c (i_c );
TVariant var_v (i_v );
TVariant var_cv(i_cv);
std::cerr << std::boolalpha;
std::cerr << std::holds_alternative< int>(var ) << std::endl;
std::cerr << std::holds_alternative<const int>(var_c ) << std::endl;
std::cerr << std::holds_alternative< volatile int>(var_v ) << std::endl;
std::cerr << std::holds_alternative<const volatile int>(var_cv) << std::endl;
std::cerr << var …Run Code Online (Sandbox Code Playgroud)