【问题标题】:Initialize an array member of class when class's copy constructor is deleted删除类的复制构造函数时初始化类的数组成员
【发布时间】:2016-05-18 11:33:07
【问题描述】:

这是我正在处理的一个较小版本的用例。

#include <mutex>
template<typename T = float>
class Foo
{
public:
    Foo(int x, int y):m_mutex(){}
private:
    std::mutex  m_mutex; // This is must have in my project
};

typedef Foo<float> Foo_typedef;

class Func
{
public:     
    static Foo_typedef static_array[2];
};

Foo_typedef Func::static_array[2] = { Foo_typedef(2,3), Foo_typedef(2,3) };

int main()
{   
    return 0;
}

编译此 VS 2015 Update 2 后会发出以下错误。

error C2280: 'Foo<float>::Foo(const Foo<float> &)': attempting to reference a deleted function
note: see declaration of 'Foo<float>::Foo'

我环顾四周,我怀疑这可能是两个原因之一。

1) std::mutex 的复制构造函数成员被删除

2) This 我认为可能与我看到的相似。

是哪一个?我该怎么做才能绕过 VS 2015 Update 2 编译器抛出的这个错误?

更新:更新了构造函数,它接受了一些需要传递给Foo_typedef的参数。

【问题讨论】:

  • 你能简单地删除初始化程序吗?即Foo_typedef Func::static_array[2];
  • Foo_typedef Func::static_array[2]{};

标签: c++ visual-c++ visual-c++-2015


【解决方案1】:

您需要使用构造函数在适当的位置构造元素:

Foo_typedef Func::static_array[2] = { {2, 3}, {2, 3} };

这样,就没有复制或移动,因为这两个元素是就地构造的

标准说(§8.5.1/2 [dcl.init.aggr],重点是我的):

当一个聚合被初始化列表初始化时,[...]初始化列表的元素被视为聚合成员的初始化 [...]。

在您的情况下,这意味着Foo_typedef(2,3) 将被视为您的Foo_typedef初始化程序,因此需要一份副本。在我给出的代码中,{2, 3} 将被视为 initializer 并调用相应的构造函数(无副本)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 2014-12-28
    相关资源
    最近更新 更多