编译器隐式删除“试图引用已删除函数”时如何解决

时间:2019-04-19 01:15:53

标签: c++ templates destructor implicit

我正在尝试创建一个通用类,该通用类可以以其最基本的形式(位)表示任何对象。为此,我创建了一个由字符数组(基本上是字节)和字符组成的对象组成的并集。不幸的是,在构建时,我为我的工会得到了一个奇怪的警告和错误。

警告:“析构函数被隐式定义为已删除。”

错误:“试图引用已删除的功能。”

(均在我的联合体定义之后的行中出现)

我知道您可以为结构,类和联合创建自定义析构函数,但是如果您不释放动态内存,则不需要吗?但是以某种方式自动调用了我从未定义的析构函数,并且编译器隐式删除了它。因此是错误。

我接下来要尝试的是在我的联合体中定义一个析构函数。它什么也没做,因为我从不要求操作系统增加内存。它再次被删除。我需要弄清楚为什么编译器会删除我的函数,然后在删除它后尝试调用它时导致错误。

我尝试在Microsoft Visual Studio列表中查找此错误,并且想到的是不公开构造函数将导致此错误。此外,在这里在线查找时,我发现通常会因未定义复制构造函数而导致错误。因此,我通过创建自己的类并使用复制构造函数=对其进行了测试。它工作得很好,但是在尝试将其与typeAsChar类一起使用时却给了我同样的错误。有趣的是,当我将类与C默认结构,int,double等一起使用时,不会调用此错误。

这是导致此问题的代码。

template <class type>
union typeAsChar
{
    type obj;
    char arr[sizeof(type)];
};

template <class type> 
class wontWork
{
public:

    wontWork() {/* Do nothing, no data entered */}
    wontWork(const type& obj) { foo.obj = obj; }
    ~wontWork() {/* When this goes out of scope, the default
                     destructor of the member 'type' should be called */}

    typeAsChar<type> foo;
};

int main()
{
    double testNum = 12345;
    std::string testStr = "Hello World\n";

    wontWork<std::string> test1(testStr); // has error
    std::cout << test1.foo.obj;

    wontWork<double> test2(testNum); // No error
    std::cout << test2.foo.obj;

        return 0;
}

奇怪的是,它在注释了wontWork<std::string>的情况下可以编译并完美运行,但是当我的类是由除标准c结构(int,double等)以外的任何对象构成的类时,此方法将失败。任何对此事的澄清将不胜感激。

1 个答案:

答案 0 :(得分:0)

这是@Miles Budnek的回答,非常有效。非常感谢您的信息,我不知道这是c ++的功能。

“ reinterpret_cast(&object)是访问组成对象的字节的明确定义的方法(即使它对std :: string之类的东西不是很有用)。通过联合进行类型划分的定义也不明确。 – Miles Budnek”