我的一个朋友向我展示了一个带有概念的 C++20 程序,这让我感到困惑:
struct A { static constexpr bool a = true; };
template <typename T>
concept C = T::a || T::b;
template <typename T>
concept D = !!(T::a || T::b);
static_assert( C<A> );
static_assert( !D<A> );
Run Code Online (Sandbox Code Playgroud)
它被所有编译器接受:https : //gcc.godbolt.org/z/e67qKoqce
这里的概念与概念D相同C,唯一的区别是双重否定运算符!!,乍一看不会改变概念值。仍然对于 struct 来说,A这个概念C是正确的,而这个概念D是错误的。
你能解释一下为什么会这样吗?
如果在C++中定义了一个新变量,则可以在初始化表达式中使用该变量的名称,例如:
int x = sizeof(x);
Run Code Online (Sandbox Code Playgroud)
那么函数参数的默认值又如何呢?是否允许通过名称引用参数?例如:
void f(int y = sizeof(y)) {}
Run Code Online (Sandbox Code Playgroud)
该函数在 Clang 中被接受,但在 GCC 中被拒绝,并出现错误:
'y' was not declared in this scope
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/YsvYnhjTb
这里是哪个编译器?
c++ compiler-errors language-lawyer function-declaration default-arguments
在以下示例中,f()返回不完整类型的函数A被标记为已删除:
struct A;
A f() = delete;
Run Code Online (Sandbox Code Playgroud)
它被 GCC 接受,但不被 Clang 接受,Clang 抱怨道:
error: incomplete result type 'A' in function definition
Run Code Online (Sandbox Code Playgroud)
演示: https: //gcc.godbolt.org/z/937PEz1h3
根据标准,哪个编译器是正确的?
以下程序抛出nullptr异常,然后捕获异常int*:
#include <iostream>
int main() {
try {
throw nullptr;
}
catch(int*) {
std::cout << "caught int*";
}
catch(...) {
std::cout << "caught other";
}
}
Run Code Online (Sandbox Code Playgroud)
在 Clang 和 GCC 中,程序成功打印caught int*, demo: https://gcc.godbolt.org/z/789639qbb
但是在 Visual Studio 16.11.2 中,程序打印caught other. 这是 MSVC 中的错误吗?
请考虑下面的简单示例,其中函数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
哪一个编译器就在这里?
Clang和 Visual Studio 编译器(但不是GCC)允许编写如下代码:
struct A
{
operator auto() { return 0; }
};
int main()
{
A a;
a.operator auto();
}
Run Code Online (Sandbox Code Playgroud)
什么是operator auto?它是特定编译器的扩展还是标准语言功能,如果是,它是在什么语言标准(例如 C++17)中出现的?
升级到最新的 Visual Studio 2022 版本 17.6 后,我们的自定义视图之一停止被识别为std::ranges::range. 事实证明,问题出在视图的迭代器中operator ==。operator !=
请找到下面的最小简化示例(已经没有视图和迭代器):
struct A {
friend bool operator ==( const A &, const A & ) = default;
};
struct B {
friend bool operator ==( const B &, const B & ) = default;
friend bool operator ==( const B &, const A & ) { return false; }
// Visual Studio 2022 version 17.6 does not like next line
friend bool operator !=( const …Run Code Online (Sandbox Code Playgroud) std::expected在最受尊敬的 stackoverflow 答案之一中,我找到了模板类用法
的示例: What are coroutines in C++20?
同时我在 cppreference.com 上找不到任何关于此类的提及。你能解释一下它是什么吗?
我的一个朋友给我看了一个 C++20 程序:
#include <iostream>
struct A
{
A() {std::cout << "A()\n";}
~A() {std::cout << "~A()\n";}
};
struct B
{
const A &a;
};
int main()
{
B x({});
std::cout << "---\n";
B y{{}};
std::cout << "---\n";
B z{A{}};
std::cout << "---\n";
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 中,它打印:
A()
~A()
---
A()
---
A()
---
~A()
~A()
Run Code Online (Sandbox Code Playgroud)
https://gcc.godbolt.org/z/ce3M3dPeo
因此,A在 y 和 z 情况下,的寿命会延长。
在 Visual Studio 中,结果是不同的:
A()
~A()
---
A()
---
A()
~A()
---
~A()
Run Code Online (Sandbox Code Playgroud)
所以A只有在 y …
C++ standard allows constexpr volatile variables per defect report 1688, which was resolved in September 2013:
The combination is intentionally permitted and could be used in some circumstances to force constant initialization.
It looks though that the intention was to allow only constinit volatile, which was not available before C++20.
Still the current compilers diverge in treatment of constexpr volatile in certain circumstances. For example, this program initializes one such variable by the other one:
int main() { …Run Code Online (Sandbox Code Playgroud) c++ ×10
c++20 ×3
c++-concepts ×2
c++-faq ×1
c++23 ×1
constexpr ×1
exception ×1
std-expected ×1
volatile ×1