小编Hol*_*Cat的帖子

在函数实现中使用命名空间

在C++中,我可以using namespace std;在函数实现文件中使用声明吗?

c++ namespaces

14
推荐指数
3
解决办法
2万
查看次数

如果使用“memory_order_relaxed”检查,为什么要使用“memory_order_seq_cst”设置停止标志?

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,但没有解释原因

看起来它会起作用,可能会有更大的停止延迟。

这是性能和其他线程看到标志的速度之间的折衷吗?即,由于主线程仅设置标志一次,我们不妨使用最强的排序,以尽快传达消息?

c++ concurrency stdatomic

13
推荐指数
1
解决办法
710
查看次数

为什么存在不同的glVertexAttribPointer变体?

glVertexAttribPointer()
glVertexAttribIPointer()
glVertexAttribLPointer()
Run Code Online (Sandbox Code Playgroud)

据我所知,glVertexAttribPointer可以用来代替其他两个.

如果是这样,为什么IL变化存在?

opengl

12
推荐指数
2
解决办法
2226
查看次数

`std::call_once` 在 Windows 上的 Clang 12 上总是段错误(使用 libstdc++ 时)

我正在寻找一种解决方法,这可能涉及修补 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)

c++ clang

12
推荐指数
1
解决办法
550
查看次数

如何直接使用 std::formatter ?

假设我想std::formatter绕过直接使用 来格式化单个对象std::format。我怎么做?

根据Formatter,我需要调用.format(value, format_ctx),其中format_ctxstd::format_contextor std::basic_format_context<...>。但我如何构建这个上下文呢?

该标准似乎没有提供一种构建方法。查看libstdc++ 源代码, 的成员变量basic_format_context都是私有的,没有非默认构造函数,并且如果不是friend.

这是否意味着std::formatter不可能按设计手动使用?


我为什么要这样做?

我想使用“调试格式”( "{?:}") 来格式化一个值(如果支持的话),回退到常规"{}".

检查支持的方法似乎是requires(std::formatter<T> f){f.set_debug_format();},我想如果我已经直接与格式化程序交互,我不妨只使用格式化程序本身。

c++ fmt stdformat

12
推荐指数
1
解决办法
367
查看次数

为什么标准容器迭代器不会重载` - >*`?

->*如果重载->,显然不能自动工作,并且必须手动重载.

为什么标准容器迭代器不超载->*除了->,迫使使用(*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)

c++ iterator operator-overloading language-lawyer

11
推荐指数
1
解决办法
169
查看次数

在自己的成员函数中构造类时,如何强制类模板参数推导?

考虑以下代码:

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)

Try it live

我理解为什么B::foo()不编译:内部struct B<T>,B(作为注入类名称)意味着B<T>除非它被明确地用作模板.在这种情况下,这会阻止类模板参数推断.

假设我不能这样做,auto foo() {return B<A>(A{});}因为我的实际代码依赖于用户提供的略微复杂的演绎指南.

问题是:在构造B内部时如何强制类模板参数推导B::foo

我希望我不会错过一些明显的东西.

c++ c++17

11
推荐指数
1
解决办法
161
查看次数

为什么不为重复的空基存储与vtable指针重叠?

考虑以下示例:

#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)

c++

11
推荐指数
1
解决办法
142
查看次数

`std::tuple_size_v` 在不同编译器上的不同 SFINAE 行为

考虑这个代码:

#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)

Run on gcc.godbolt.org

在 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)

c++ language-lawyer c++20

11
推荐指数
1
解决办法
391
查看次数

最新 gcc 的未定义参考问题

尝试使用 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 回归还是这段代码有问题?

c++ gcc templates compiler-errors linkage

11
推荐指数
1
解决办法
1524
查看次数