C++ 如果类是不完整类型,为什么要编译?
在内存中,我有:C++ 如果类是不完整类型,为什么要编译?,c++,incomplete-type,template-instantiation,C++,Incomplete Type,Template Instantiation,在内存中,我有: #pragma once class Memory {public: template <typename T, typename ... TArgs> static T* newAlloc(TArgs ... args) { return new T(args ...); } }; ???因为这没有编译,所以我得到了错误: 未找到“newAlloc”标识符“newAlloc”不是的成员 记忆 基本上,它需要Foo
#pragma once
class Memory
{public:
template <typename T, typename ... TArgs>
static T* newAlloc(TArgs ... args)
{
return new T(args ...);
}
};
???因为这没有编译,所以我得到了错误:
未找到“newAlloc”标识符“newAlloc”不是的成员
记忆
基本上,它需要Foo的完整定义。如果我将Foo类定义放在内存定义之上,那么它就可以很好地编译。既然我的第二个版本相当于模板实例化后的代码(是吗?),那么为什么第一个版本编译而第二个版本不编译呢
我使用的是Visual Studio 2019 16.4.5
编译器粘贴到内存后的等效代码不是吗。h在main.cpp中是这样的:
class Memory
{
public:
static Foo* newAlloc(int a, const char* c)
{
return new Foo(a, c);
}
};
class Foo
{public:
Foo(int a, const char* c) {}
};
int main()
{
Memory::newAlloc(7, "str");
}
不,这不是真的。这相当于:
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");
}
类内存
{公众:
模板
静态T*newAlloc(目标…参数)
{
返回新的T(参数…);
}
};
福班
{公众:
Foo(inta,constchar*c){}
};
int main()
{
内存:newAlloc(7,“str”);
}
你会发现它可以编译
为什么第一个版本要编译
它之所以有效,是因为在使用Foo
作为模板参数实例化模板之前定义了Foo
编译器粘贴到内存后的等效代码不是吗。h在main.cpp中是这样的:
class Memory
{
public:
static Foo* newAlloc(int a, const char* c)
{
return new Foo(a, c);
}
};
class Foo
{public:
Foo(int a, const char* c) {}
};
int main()
{
Memory::newAlloc(7, "str");
}
不,这不是真的。这相当于:
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");
}
类内存
{公众:
模板
静态T*newAlloc(目标…参数)
{
返回新的T(参数…);
}
};
福班
{公众:
Foo(inta,constchar*c){}
};
int main()
{
内存:newAlloc(7,“str”);
}
你会发现它可以编译
为什么第一个版本要编译
它之所以有效,是因为在使用Foo
作为模板参数实例化模板之前定义了Foo
即使在我粘贴到Memory.h之后才完全定义Foo,这也可以很好地编译
是的,因为在这里实例化Memory::newAlloc
时:
Memory::newAlloc(7, "str");
Foo
的定义已经存在,因此编译起来很好
编译器粘贴到内存后的等效代码不是吗。h在main.cpp中是这样的:
class Memory
{
public:
static Foo* newAlloc(int a, const char* c)
{
return new Foo(a, c);
}
};
class Foo
{public:
Foo(int a, const char* c) {}
};
int main()
{
Memory::newAlloc(7, "str");
}
不,在本例中,在这一行:
static Foo* newAlloc(int a, const char* c)
由于尚未定义Foo
,因此代码将不会编译
即使在我粘贴到Memory.h之后才完全定义Foo,这也可以很好地编译
是的,因为在这里实例化Memory::newAlloc
时:
Memory::newAlloc(7, "str");
Foo
的定义已经存在,因此编译起来很好
编译器粘贴到内存后的等效代码不是吗。h在main.cpp中是这样的:
class Memory
{
public:
static Foo* newAlloc(int a, const char* c)
{
return new Foo(a, c);
}
};
class Foo
{public:
Foo(int a, const char* c) {}
};
int main()
{
Memory::newAlloc(7, "str");
}
不,在本例中,在这一行:
static Foo* newAlloc(int a, const char* c)
由于尚未定义
Foo
,代码将不会编译。#include
是一个简单的复制粘贴,但tempate实例化并不是那么简单的机制。无需实际将生成的代码放在任何地方,只要编译器知道它应该做什么就足够了。Memory::newAlloc
在main
中实例化,其中Foo
的定义已完成。您可以使用模板进行一些操作。您正在询问著名的“两阶段查找”.#include
是一种简单的复制粘贴,但tempate实例化并不是那么简单的机制。无需实际将生成的代码放在任何地方,只要编译器知道它应该做什么就足够了。Memory::newAlloc
在main
中实例化,其中Foo
的定义已完成。您可以使用模板进行一些操作。您正在询问著名的“两阶段查找”。