为什么 tbb::enumerable_thread_specific 不接受构造函数参数中带有非 const 引用的类型?

问题描述 投票:0回答:1

我想使用

tbb::enumerable_thread_specific
为构造函数中采用非 const 引用的类型元素创建线程本地存储。不幸的是,它不能直接使用,我必须使用
std::ref
进行构建作为解决方法。这是一个例子:

#include <tbb/enumerable_thread_specific.h>

struct A {
    A(int &) {}
};

int main() {
    int i;

    // ok
    tbb::enumerable_thread_specific<A> ets1(std::ref(i));

    // error
    tbb::enumerable_thread_specific<A> ets(i);
}

错误是

In file included from /opt/compiler-explorer/libs/tbb/2021.4.0/include/tbb/enumerable_thread_specific.h:17,
                 from <source>:1:
/opt/compiler-explorer/libs/tbb/2021.4.0/include/oneapi/tbb/enumerable_thread_specific.h: In instantiation of 'void tbb::detail::d1::construct_by_args<T, P>::construct(void*) [with T = A; P = {int&}]':
/opt/compiler-explorer/libs/tbb/2021.4.0/include/oneapi/tbb/enumerable_thread_specific.h:685:31:   required from 'void tbb::detail::d1::callback_leaf<Constructor>::construct(void*) [with Constructor = tbb::detail::d1::construct_by_args<A, int&>]'
/opt/compiler-explorer/libs/tbb/2021.4.0/include/oneapi/tbb/enumerable_thread_specific.h:684:10:   required from here
/opt/compiler-explorer/libs/tbb/2021.4.0/include/oneapi/tbb/enumerable_thread_specific.h:648:12: error: binding reference of type 'int&' to 'const std::decay<int&>::type' {aka 'const int'} discards qualifiers
  648 |            new(where) T(args...);
      |            ^~~~~~~~~~~~~~~~~~~~~
<source>:4:7: note:   initializing argument 1 of 'A::A(int&)'
    4 |     A(int &) {}
      |       ^~~~~

在线演示:https://godbolt.org/z/qGx7cGz44

看起来非 const 引用在到达

A
构造函数之前就在 TBB 中变成了 const 引用。这是有意的设计决策还是只是实施中的错误?

c++ multithreading tbb
1个回答
0
投票

这基本上已经在 463035818_is_not_an_ai 的评论中得到了回答,将其与 std::thread 背后的相同逻辑相关联,然后链接了关于 ref 与线程的相同显式使用的答案。

您在构造函数参数中遇到的 tbb::enumerable_thread_specific 和非常量引用问题与 tbb::enumerable_thread_specific 的设计有关。该库使用底层机制来构造和管理存储类型的实例,并且该机制依赖于该类型的某些特征。

当您在构造函数参数中提供非常量引用时,它可能会导致线程安全和对象管理方面的复杂化。 enumerable_thread_specific 旨在跨多个线程有效地管理类型实例,并且以线程安全的方式处理非常量引用可能具有挑战性。

正如您已经发现的,您可以使用 std::reference_wrapper 或指针而不是非常量引用。

© www.soinside.com 2019 - 2024. All rights reserved.