如果类是不完整类型,为什么要编译呢?

问题描述

在Memory.h中,我有:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table style="background:#c3c3c3" id="t_1">
  <tbody>
    <tr class="amenities-row" id="ar_1">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_1" id="am_1" value="1" disabled>
          <label for="am_1">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_1" type="checkbox" value="1" checked>
          <label for="checkbox_am_1">
                    </label>
        </div>
      </td>
      <td>
        Amenity 1
      </td>
    </tr>
    <tr class="amenities-row" id="ar_2">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_1" id="am_2" value="1" disabled>
          <label for="am_2">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_2" type="checkbox" value="1" checked>
          <label for="checkbox_am_2">
                    </label>
        </div>
      </td>
      <td>
        Amenity 2
      </td>
    </tr>
    <tr class="amenities-row" id="ar_3">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_1" id="am_3" value="1">
          <label for="am_3">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_3" type="checkbox" value="1" checked>
          <label for="checkbox_am_3">
                    </label>
        </div>
      </td>
      <td>
        Amenity 3
      </td>
    </tr>
    <tr class="amenities-row" id="ar_4">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_1" id="am_4" value="1" disabled>
          <label for="am_4">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_4" type="checkbox" value="1" checked>
          <label for="checkbox_am_4">
                    </label>
        </div>
      </td>
      <td>
        Amenity 4
      </td>
    </tr>
  </tbody>
</table>

<table id="t_2">
  <tbody>
    <tr class="amenities-row" id="ar_5">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_2" id="am_5" value="1">
          <label for="am_5">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_5" type="checkbox" value="1" checked>
          <label for="checkbox_am_5">
                    </label>
        </div>
      </td>
      <td>
        Amenity 5
      </td>
    </tr>
    <tr class="amenities-row" id="ar_6">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_2" id="am_6" value="1">
          <label for="am_6">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_6" type="checkbox" value="1" checked>
          <label for="checkbox_am_6">
                    </label>
        </div>
      </td>
      <td>
        Amenity 6
      </td>
    </tr>
    <tr class="amenities-row" id="ar_7">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_2" id="am_7" value="1" disabled>
          <label for="am_7">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_7" type="checkbox" value="1" checked>
          <label for="checkbox_am_7">
                    </label>
        </div>
      </td>
      <td>
        Amenity 7
      </td>
    </tr>
    <tr class="amenities-row" id="ar_8">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_2" id="am_8" value="1" disabled>
          <label for="am_8">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_8" type="checkbox" value="1" checked>
          <label for="checkbox_am_8">
                    </label>
        </div>
      </td>
      <td>
        Amenity 8
      </td>
    </tr>
  </tbody>
</table>
<table id="t_3" style="background:lime">
  <tbody>
    <tr class="amenities-row" id="ar_9">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_3" id="am_9" value="1" disabled>
          <label for="am_9">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_9" type="checkbox" value="1" checked>
          <label for="checkbox_am_9">
                    </label>
        </div>
      </td>
      <td>
        Amenity 9
      </td>
    </tr>
    <tr class="amenities-row" id="ar_10">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_3" id="am_10" value="1" disabled>
          <label for="am_10">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_10" type="checkbox" value="1" checked>
          <label for="checkbox_am_10">
                    </label>
        </div>
      </td>
      <td>
        Amenity 10
      </td>
    </tr>
    <tr class="amenities-row" id="ar_11">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_3" id="am_11" value="1" disabled>
          <label for="am_11">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_11" type="checkbox" value="1" checked>
          <label for="checkbox_am_11">
                    </label>
        </div>
      </td>
      <td>
        Amenity 11
      </td>
    </tr>
    <tr class="amenities-row" id="ar_12">
      <td>
        <div class="radio radio-info pl-2">
          <input type="radio" name="base_cat_3" id="am_12" value="1" disabled>
          <label for="am_12">
                    </label>
        </div>
      </td>
      <td>
        <div class="checkbox checkbox-info pl-2">
          <input name="selected_am" id="checkbox_am_12" type="checkbox" value="1" checked>
          <label for="checkbox_am_12">
                    </label>
        </div>
      </td>
      <td>
        Amenity 12
      </td>
    </tr>
  </tbody>
</table>

在main.cpp中,我有:

#pragma once

class Memory
{public:
    template <typename T,typename ... TArgs>
    static T* newAlloc(TArgs ... args)
    {
        return new T(args ...);
    }
};

即使在我粘贴Memory.h之后才完全定义Foo,这也可以正常编译。我对为什么编译感到困惑。编译器粘贴到Memory.h之后的等效代码不是真的吗,就像main.cpp中这样:

#include "Memory.h" // The template class is defined here

class Foo
{public:
    Foo(int a,const char* c) {}
};

int main()
{
    Memory::newAlloc<Foo>(7,"str");

}

???由于无法编译,因此出现错误:

找不到'newAlloc'标识符'newAlloc'不是以下成员 记忆

基本上,它需要Foo的完整定义。如果我将Foo类定义放在Memory 1之上,则可以正常编译。因此,考虑到我的第二个版本等效于模板实例化之后的代码(是吗?),那么为什么第一个版本可以编译而第二个版本不能编译?

我正在使用Visual Studio 2019 16.4.5

解决方法

在编译器粘贴到Memory.h中后,等效代码是否正确,就像main.cpp中这样:

不,这不是事实。这将是等效的:

class Memory
{public:
    template <typename T,typename ... TArgs>
    static T* newAlloc(TArgs ... args)
    {
        return new T(args ...);
    }
};


class Foo
{public:
    Foo(int a,const char* c) {}
};

int main()
{
    Memory::newAlloc<Foo>(7,"str");

}

您会发现它可以编译。

为什么第一个版本会编译

之所以有效,是因为Foo是在模板以Foo作为模板参数实例化之前定义的。

,

即使Foo直到我粘贴到Memory.h之后才完全定义,它仍可以正常编译

是的,因为在这里实例化了Memory::newAlloc时:

Memory::newAlloc(7,"str");

Foo的定义已经存在,因此可以很好地编译。


在编译器粘贴到Memory.h中后,等效代码是否正确,就像main.cpp中这样:

在这种情况下,不在此行上:

static Foo* newAlloc(int a,const char* c)

由于尚未定义Foo,因此代码将无法编译。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...