这是一个简单的,自包含的,不可编译的gcc-4.8.2我想要完成的例子:
#include <atomic>
template <typename T>
class ValueParameter
{
public:
ValueParameter() = default;
ValueParameter(T initialValue) :
_val(initialValue)
{
}
private:
std::atomic<T> _val{T()};
};
ValueParameter<int> x;
我已经在其他几个gcc版本上成功编译了这个版本,包括5.3,但是gcc 4.8.2失败并出现以下错误:
/tmp/gcc-explorer-compiler11658-82-1cqz6ui/example.cpp: In constructor 'ValueParameter<T>::ValueParameter() [with T = int]':
7 : error: use of deleted function 'std::atomic<int>::atomic(const std::atomic<int>&)'
ValueParameter() = default;
^
In file included from /tmp/gcc-explorer-compiler11658-82-1cqz6ui/example.cpp:1:0:
You can see the results online here
我理解std::atomic<T>
是不可复制的,但对我来说没有任何意义,因为编译器会尝试在默认构造函数中使用复制构造函数。我确实发现改变了这条线:
std::atomic<T> _val{T()};
到
std::atomic<T> _val;
使文件编译成功。统一初始化是来自该类的先前版本的遗留物,其没有构造函数采用初始值。
这应该是错误吗?此外,在这种情况下,我期望应该的行为,其中成员被初始化为内联类和构造函数初始化列表?我希望默认构造函数将val
初始化为T()
,所以我认为我需要大括号初始化器。
答案 0 :(得分:3)
这绝对是一个gcc bug,而且他们已经修复了4.9。您的代码在任何时候都不会调用ValueParameter<T>
的复制构造函数 - 因此不应该实例化成员函数。使用atomic<T>
的默认成员初始化程序很好 - 它确实可以从T
构建。
此外,在这种情况下,我应该期望什么行为,其中成员被初始化为内联类和构造函数初始化列表?
默认成员初始值设定项就是 - 默认值。如果您在mem-initializer-list中提供了初始值设定项(就像在ValueParameter(T )
构造函数中那样),则忽略默认值。如果您没有提供这样的初始化程序(因为您不在ValueParameter()
中),则使用默认值。
我希望默认构造函数将val初始化为
T()
,所以我想我需要大括号初始化器。
您的代码应该完全按照您的意愿执行。 gcc 4.8这里有个bug。