在默认的默认构造函数中调用复制构造函数时,gcc 4.8.2是否正确?

时间:2016-06-08 15:42:15

标签: c++ c++11 constructor

这是一个简单的,自包含的,不可编译的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(),所以我认为我需要大括号初始化器。

1 个答案:

答案 0 :(得分:3)

这绝对是一个gcc bug,而且他们已经修复了4.9。您的代码在任何时候都不会调用ValueParameter<T>的复制构造函数 - 因此不应该实例化成员函数。使用atomic<T>的默认成员初始化程序很好 - 它确实可以从T构建。

  

此外,在这种情况下,我应该期望什么行为,其中成员被初始化为内联类和构造函数初始化列表?

默认成员初始值设定项就是 - 默认值。如果您在mem-initializer-list中提供了初始值设定项(就像在ValueParameter(T )构造函数中那样),则忽略默认值。如果您没有提供这样的初始化程序(因为您不在ValueParameter()中),则使用默认值。

  

我希望默认构造函数将val初始化为T(),所以我想我需要大括号初始化器。

您的代码应该完全按照您的意愿执行。 gcc 4.8这里有个bug。