Herb Sutter 在他的“原子<>武器”演讲中展示了原子的几个示例用途,其中之一可归结为以下内容:(视频链接,带时间戳)
一个主线程启动多个工作线程。
工人检查停止标志:
while (!stop.load(std::memory_order_relaxed))
{
// Do stuff.
}
Run Code Online (Sandbox Code Playgroud)
主线程最终执行此操作stop = true;(注意,使用 order= seq_cst),然后加入工作线程。
Sutter 解释说,使用 order= 检查标志relaxed是可以的,因为谁在乎线程是否会因稍大的延迟而停止。
但为什么要stop = true;在主线程中使用呢seq_cst?幻灯片上说这是故意不这样做relaxed,但没有解释原因。
看起来它会起作用,可能会有更大的停止延迟。
这是性能和其他线程看到标志的速度之间的折衷吗?即,由于主线程仅设置标志一次,我们不妨使用最强的排序,以尽快传达消息?
有
glVertexAttribPointer()
glVertexAttribIPointer()
glVertexAttribLPointer()
Run Code Online (Sandbox Code Playgroud)
据我所知,glVertexAttribPointer可以用来代替其他两个.
如果是这样,为什么I和L变化存在?
我正在寻找一种解决方法,这可能涉及修补 libstdc++ 标头。保留二进制兼容性是首选但不是强制性的,因为除了 libstdc++ 之外,我没有使用任何预编译的 C++ 代码。
我想保留std::call_once接口,因为我正在尝试编译使用 is 的第三方代码,我不想更改它。
这是我的代码:
#include <iostream>
#include <mutex>
int main()
{
std::once_flag flag;
std::call_once(flag, []{std::cout << "Once!\n";});
}
Run Code Online (Sandbox Code Playgroud)
运行它会导致分段错误。
我使用 Clang 12 将它从 Ubuntu 交叉编译到 Windows,使用 MSYS2 GCC 10.2 的标准库。然后我用 Wine 测试结果(一个快速测试表明它在虚拟机上也崩溃了)。但是您应该能够通过在 Windows 上本地编译来重现结果(使用官方 Clang 二进制文件 + MSYS2 GCC,因为 MSYS2 还没有 Clang 12)。
我是这样编译的:
clang++-12 1.cpp --target=x86_64-w64-mingw32 --sysroot=/mingw64 -pthread -femulated-tls
Run Code Online (Sandbox Code Playgroud)
如果我添加-g,GDB 显示如下:
Program received signal SIGSEGV, Segmentation fault.
0x00000001e014dc4a in ?? () from Z:\home\holyblackcat\Sandbox\2\libgcc_s_seh-1.dll
(gdb) bt
#0 0x00000001e014dc4a in …Run Code Online (Sandbox Code Playgroud) 假设我想std::formatter绕过直接使用 来格式化单个对象std::format。我怎么做?
根据Formatter,我需要调用.format(value, format_ctx),其中format_ctx是std::format_contextor std::basic_format_context<...>。但我如何构建这个上下文呢?
该标准似乎没有提供一种构建方法。查看libstdc++ 源代码, 的成员变量basic_format_context都是私有的,没有非默认构造函数,并且如果不是friend.
这是否意味着std::formatter不可能按设计手动使用?
我为什么要这样做?
我想使用“调试格式”( "{?:}") 来格式化一个值(如果支持的话),回退到常规"{}".
检查支持的方法似乎是requires(std::formatter<T> f){f.set_debug_format();},我想如果我已经直接与格式化程序交互,我不妨只使用格式化程序本身。
->*如果重载->,显然不能自动工作,并且必须手动重载.
为什么标准容器迭代器不超载->*除了->,迫使使用(*iter).*mem_ptr代替iter->*mem_ptr?
#include <iostream>
#include <vector>
struct S
{
int x;
};
int main()
{
std::vector<S> vec = {{42}};
auto mem_ptr = &S::x;
std::cout << (*vec.begin()).*mem_ptr << '\n'; // This line compiles.
std::cout << vec.begin()->*mem_ptr << '\n'; // This line doesn't compile.
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
struct A {};
template <typename T> struct B
{
B(T) {}
auto foo() {return B(A{});} // error: no matching function for call to 'B<int>::B(A)'
};
auto foo() {return B(A{});} // compiles
int main()
{
foo();
B b(0);
b.foo();
}
Run Code Online (Sandbox Code Playgroud)
我理解为什么B::foo()不编译:内部struct B<T>,B(作为注入类名称)意味着B<T>除非它被明确地用作模板.在这种情况下,这会阻止类模板参数推断.
假设我不能这样做,auto foo() {return B<A>(A{});}因为我的实际代码依赖于用户提供的略微复杂的演绎指南.
问题是:在构造B内部时如何强制类模板参数推导B::foo?
我希望我不会错过一些明显的东西.
考虑以下示例:
#include <iostream>
int main()
{
struct A {};
struct B : A {};
struct C : A, B {};
std::cout << sizeof(A) << '\n'; // 1
std::cout << sizeof(B) << '\n'; // 1
std::cout << sizeof(C) << '\n'; // 2, because of a duplicate base
struct E : A {virtual ~E() {}};
struct F : A, B {virtual ~F() {}};
std::cout << sizeof(E) << '\n'; // 8, the base overlaps the vtable pointer
std::cout << sizeof(F) << '\n'; // …Run Code Online (Sandbox Code Playgroud) 考虑这个代码:
#include <tuple>
#include <type_traits>
#include <iostream>
template <typename T, typename = void> struct is_tuple_like : std::false_type {};
template <typename T> struct is_tuple_like<T, decltype(std::tuple_size_v<T>, void())> : std::true_type {};
int main()
{
std::cout << is_tuple_like<std::string>::value << '\n';
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 10.2 和 MSVC 19.28 上,它会导致硬错误,如下所示:
#include <tuple>
#include <type_traits>
#include <iostream>
template <typename T, typename = void> struct is_tuple_like : std::false_type {};
template <typename T> struct is_tuple_like<T, decltype(std::tuple_size_v<T>, void())> : std::true_type {};
int main()
{
std::cout << is_tuple_like<std::string>::value …Run Code Online (Sandbox Code Playgroud) 尝试使用 gcc 12.1.0 编译以下代码时出现链接时错误。使用 clang、msvc 和较旧的 gcc,它可以按预期进行编译。
template<typename T>
void def()
{}
template<void (*foobar)() = def<int>>
void bar()
{
foobar();
}
template<typename T>
void foo()
{
bar();
}
int main()
{
foo<int>();
}
Run Code Online (Sandbox Code Playgroud)
Error: /usr/bin/ld: /tmp/cchkaKVw.o: in function `void bar<&(void def<int>())>()':
> main.cpp:(.text._Z3barIXadL_Z3defIiEvvEEEvv[_Z3barIXadL_Z3defIiEvvEEEvv]+0x5): undefined reference to `void def<int>()'
Run Code Online (Sandbox Code Playgroud)
这是 gcc 回归还是这段代码有问题?