C++编译器错误 "由于具有非POD类型,无法成为线程本地变量"

5
这条语句:
___thread A a;

生成以下错误:

由于具有非POD类型,因此无法成为线程本地变量

A是什么:

class A{
       public:
               // function declaration
       private:
               // data members
};

我正在尝试在Linux上编译这个程序,使用的命令包括ogs和ogs mk。我们有静态线程,即在应用程序运行之前,我们就知道线程的数量,因此目前的解决方法是声明A数组。

A a[Number of threads].

我该如何解决这个问题?

2
看看 __thread A* a; 来领先一步。 - Hans Passant
2个回答

2
假设您使用的是 gcc,线程本地存储仅支持 POD 类型,即仅包含数据的结构。您可以尝试将数据提取到单独的 struct 中并使其成为线程本地的(实际上,在任何情况下都是一个好主意,因为将方法设置为线程本地没有太多意义)。

请注意,您可以将所有数据成员设置为private,并在单独的friend类中编写方法。 - ecatmur
谢谢icepack。然而我没有访问A类模板,因此我无法将A类更改为结构体A。A类已经被广泛使用,因此我需要尽可能避免对A类进行更改。我们考虑的另一个解决方法是在全局头文件中声明__thread A *a;,并在线程初始化函数中使用a = new A()。但现在我们不想从堆中分配类A的内存,所以无论如何我们都需要使语句__thread A a;正常工作。 - Cpp Developer
如果您对类的动态分配/释放没有问题,那么我认为这个代码没有任何问题。您的“a”实际上是一个所需的“POD”。否则,您需要对“A”本身进行更改。最干净的方法似乎是@ecatmur建议的方法。 - SomeWittyUsername

1

很遗憾,在C++03中没有动态初始化(和销毁)线程本地资源的功能(它们对线程一无所知)。

在C++11中,thread_local存储关键字允许动态初始化,但会带来运行时开销(基本上相当于具有线程本地静态变量),因此可以在没有构造函数的类型中使用。

同样在C++11中,constexpr构造函数可以用于静态初始化,并且应与__thread说明符兼容,前提是您的编译器实现了它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接