我有一种情况,我希望 C++ switch 语句中的两种情况都落入第三种情况。具体来说,第二种情况会落入第三种情况,而第一种情况也会落入第三种情况,而不会经过第二种情况。
我有一个愚蠢的想法,尝试了一下,它奏效了!我将第二个箱子包裹在一个if (0) {... }. 它看起来像这样:
#ifdef __cplusplus
# include <cstdio>
#else
# include <stdio.h>
#endif
int main(void) {
for (int i = 0; i < 3; i++) {
printf("%d: ", i);
switch (i) {
case 0:
putchar('a');
// @fallthrough@
if (0) { // fall past all of case 1 (!)
case 1:
putchar('b');
// @fallthrough@
}
case 2:
putchar('c');
break;
}
putchar('\n');
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我得到了所需的输出:
0: ac
1: bc …Run Code Online (Sandbox Code Playgroud) #include <compare>
struct A
{
int n;
auto operator<=>(A const& other) const
{
if (n < other.n)
{
return std::strong_ordering::less;
}
else if (n > other.n)
{
return std::strong_ordering::greater;
}
else
{
return std::strong_ordering::equal;
}
}
// compile error if the following code is commented out.
// bool operator==(A const& other) const
// { return n == other.n; }
};
int main()
{
A{} == A{};
}
Run Code Online (Sandbox Code Playgroud)
看在线演示
为什么我必须 operator == 在 足够的时候提供operator <=> ?
c++ language-design language-lawyer spaceship-operator c++20
我试图std::pair用这种风格制作:
#include <iostream>
struct A {
A() noexcept {
std::cout << "Created\n";
}
A(const A&) noexcept {
std::cout << "Copy\n";
}
A(A&&) noexcept {
std::cout << "Move\n";
}
};
int main() {
std::pair<A, A> a{ {},{} };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并得到这样的输出:
Created
Created
Copy
Copy
Run Code Online (Sandbox Code Playgroud)
代替
Created
Created
Move
Move
Run Code Online (Sandbox Code Playgroud)
但是如果我定义我的匿名对象类型(例如std::pair<A, A> a{A{}, A{}})或使用std::make_pair<A, A>({}, {})我得到正确的结果。
std::pair构造函数必须使用std::forward<U1>和std::forward<U2>来初始化对象,因此我认为我的配对使用了错误的构造函数。为什么?
在 C++20 中有一些关于重写比较运算符的新规则,我试图了解它们是如何工作的。我遇到了以下程序:
struct B {};
struct A
{
bool operator==(B const&); // #1
};
bool operator==(B const&, A const&); // #2
int main()
{
B{} == A{}; // C++17: calls #2
// C++20: calls #1
}
Run Code Online (Sandbox Code Playgroud)
这实际上破坏了现有的代码。我对此感到有些惊讶;#2实际上对我来说仍然看起来更好:p
那么这些新规则如何改变现有代码的含义呢?
请考虑下面的简单示例,其中函数bar返回A具有私有析构函数的类对象,并且必须进行强制返回值优化(RVO):
class A { ~A() = default; };
A bar() { return {}; }
Run Code Online (Sandbox Code Playgroud)
该代码被 Clang 接受,但被 GCC 拒绝并出现错误:
error: 'constexpr A::~A()' is private within this context
2 | A bar() { return {}; }
| ^
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/q6c33absK
哪一个编译器就在这里?
在C和C++中,当要复制的字节数为零时,memcpy进入变量是否是未定义的行为?const
int x = 0;
const int foo = 0;
memcpy( (void *)&foo, &x, 0 );
Run Code Online (Sandbox Code Playgroud)
这个问题并不纯粹是理论上的。我有一个场景,其中memcpy被调用,如果目标指针指向const内存,则大小参数保证为零。所以我想知道是否需要将其作为特殊情况处理。
考虑以下程序:
#include <iostream>
int const * f(int const &i)
{
return &i;
}
int main()
{
std::cout << f(42); // #1
std::cout << f(42); // #2
std::cout << f(42) << f(42); // #3
}
Run Code Online (Sandbox Code Playgroud)
根据编译器和设置的优化级别,打印在行上的地址可能彼此不同#1,#2也可能不同。
但是,无论选择何种编译器或优化级别,行#3中打印的 2 个地址总是彼此不同。
这是一个可以玩的演示。
那么f在每种情况下返回什么的规则是什么?
例如:
class B;
class A {
public:
B f();
};
int main(int, char**) {
A a; // no exception and error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该类A可能是不完整的类型。
为什么A这个例子中可以实例化类呢?
f我知道当代码中调用成员函数时,程序将无法编译。