*******编辑*******C++编译问题 - 用cl.exe编译正常,但不会从Visual Studio 2015编译
一位读者建议我的问题是重复的的问题发现here。在包头结束
- 1)的#include实现文件(这是我做我的解决方案)或
- 2)显式实例所有的:对这个问题的回应领先给出了两个解决方案模板实例我需要在实现文件的末尾
由于我已经尝试过这种解决方案,这不是重复的问题。
这个问题,正如下面的Ben Voigt所说(谢谢),与Visual Studio有关。将“C/C++编译器”的“项目类型”更改为“C/C++头文件”以解决MyClass.cpp文件问题。
****编辑完****
我是一个初学者C++和我遇到一个问题,试图在Visual Studio 2015年编译下面的程序中的程序中使用精编铛编译器在我的Mac上。该程序也使用VS2015的开发人员命令提示符使用cl.exe进行了良好编译。我想这意味着有些东西在我的Visual Studio项目中配置错误,但我还没有找到解决方案。
下面的代码:
/** @file MyInterface.h */
#ifndef MY_INTERFACE_
#define MY_INTERFACE_
template<class ItemType>
class MyInterface
{
public:
virtual void sayHello() const = 0;
};
#endif
/** @file MyClass.h */
#ifndef MY_CLASS_
#define MY_CLASS_
#include "MyInterface.h"
template<class ItemType>
class MyClass : public MyInterface<ItemType>
{
private:
ItemType myItem;
public:
MyClass();
void setItem(const ItemType& newItem);
void sayHello() const;
};
#include "MyClass.cpp"
#endif
/** Implementation file for MyClass.
@file MyClass.cpp */
#include "MyClass.h"
#include <iostream>
template<class ItemType>
MyClass<ItemType>::MyClass()
{
}
template<class ItemType>
void MyClass<ItemType>::setItem(const ItemType& newItem)
{
myItem = newItem;
}
template<class ItemType>
void MyClass<ItemType>::sayHello() const
{
std::cout << "Hello! My Item is: " << myItem << std::endl;
}
/** @file test.cpp */
#include "MyClass.h"
#include <string>
int main()
{
MyClass<std::string> classOne;
classOne.setItem("foo");
classOne.sayHello();
MyClass<int> classTwo;
classTwo.setItem(7);
classTwo.sayHello();
}
当我在一个目录合并这些文件并运行命令:
cl test.cpp
从VS2015开发人员命令提示符,它编译正确。我得到一个test.exe可执行文件返回:
test.exe
Hello! My item is: foo
Hello! My item is: 7
到目前为止,这么好。
当我尝试在Visual Studio 2015中完成此项目时,问题就开始了。我为Visual C++启动了一个“空项目”并添加了这些完全相同的文件。然而,当我建立这个项目我得到的错误信息:
Error C2995 'MyClass<ItemType>::MyClass(void)': function template has already been defined
Error C2995 'void MyClass<ItemType>::setItem(const ItemType &)': function template has already been defined
Error C2995 'void MyClass<ItemType>::sayHello(void) const': function template has already been defined
错误信息让我相信,我有一个循环依赖。罪魁祸首似乎是MyClass.h文件中的#include "MyClass.cpp"
,但这对模板编译是必需的。如果没有这个包含,编译器就无法看到模板的实例化,也不知道对应于泛型ItemType
(或者我的教科书说)的实际数据类型。
在努力满足Visual Studio的生成过程中,我从MyClass.h文件中删除了#include "MyClass.cpp
,但后来我得到这些错误:
Error LNK2019 unresolved external symbol "public: __thiscall MyClass<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::MyClass<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" ([email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@@[email protected]) referenced in function _main
Error LNK2019 unresolved external symbol "public: __thiscall MyClass<int>::MyClass<int>(void)" ([email protected]@@[email protected]) referenced in function _main
Error LNK2019 unresolved external symbol "public: void __thiscall MyClass<int>::setItem(int const &)" ([email protected][email protected]@@[email protected]) referenced in function _main
有六个这样的错误(仅示出三个),都是未解析的外部符号。
在这一点上,我不知道还有什么要尝试。如果我将实现文件包含在头文件中,编译器会大声说我有循环依赖关系,如果我不在头文件中包含实现文件,那么我有无法解析的外部符号。
在这个问题上的任何帮助,将不胜感激:)
模板定义需要在.h文件中,并且您不应该#include一个.cpp文件。 –
http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented -in-the-header-file – drescherjm
@latedeveloper:这是一个惯例,而不是一个需要。 –