C++ c++;编译问题--可以使用cl.exe编译,但不会从Visual Studio 2015编译

C++ c++;编译问题--可以使用cl.exe编译,但不会从Visual Studio 2015编译,c++,visual-studio-2015,C++,Visual Studio 2015,*******编辑******* 一位读者表示,我的问题与所发现的问题重复。对这个问题的主要回答给出了两种解决方案: 1) #在头的末尾包含实现文件(这是我在解决方案中所做的),或者 2) 在实现文件末尾显式实例化我需要的所有模板实例 因为我已经尝试过这个解决方案,所以这不是一个重复的问题 正如下面Ben Voigt(谢谢)所述,这个问题与Visual Studio有关。将MyClass.cpp文件的“项类型”从“C/C++编译器”更改为“C/C++头”,解决了此问题 ****结束编辑***

*******编辑*******

一位读者表示,我的问题与所发现的问题重复。对这个问题的主要回答给出了两种解决方案:

  • 1) #在头的末尾包含实现文件(这是我在解决方案中所做的),或者
  • 2) 在实现文件末尾显式实例化我需要的所有模板实例
因为我已经尝试过这个解决方案,所以这不是一个重复的问题

正如下面Ben Voigt(谢谢)所述,这个问题与Visual Studio有关。将MyClass.cpp文件的“项类型”从“C/C++编译器”更改为“C/C++头”,解决了此问题

****结束编辑****

我是C++初学者,我正在尝试在VisualStudio 2015中编译以下程序。这个程序在我的Mac电脑上使用铿锵编译器编译得很好。该程序还使用VS2015的开发者命令提示符中的cl.exe进行了良好编译。我想这意味着我的VisualStudio项目配置有问题,但我还没有找到解决方案

代码如下:

/** @file MyInterface.h */

#ifndef MY_INTERFACE_
#define MY_INTERFACE_

template<class ItemType>
class MyInterface
{
public:
    virtual void sayHello() const = 0;
};

#endif
从VS2015的开发者命令提示符,它可以正确编译。我得到一个test.exe可执行文件,该文件返回:

test.exe
Hello! My item is: foo
Hello! My item is: 7
到目前为止,一切顺利

当我试图在Visual Studio 2015内完成此项目时,问题就开始了。为VisualC++添加了一个“空项目”,并添加了完全相同的文件。但是,当我构建项目时,会收到以下错误消息:

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
有六个这样的错误(只显示了三个),都是未解析的外部符号

在这一点上,我不知道还有什么可以尝试。如果我在头文件中包含了实现文件,编译器会因为我有循环依赖关系而对我大喊大叫,如果我没有在头文件中包含实现文件,则我有未解析的外部符号

对此问题的任何帮助都将不胜感激:)

因为您的
#include
MyClass.cpp,它本身不是编译单元,而是头文件。确保Visual Studio被告知不要尝试单独构建它,默认情况下,它假定
.h
文件是头文件,
.cpp
都是单独编译的单元

访问项目属性并将“项目类型”从“C/C++编译器”更改为“C/C++头”

这将有效地将build命令更改为工作版本

cl test.cpp
通过添加所有文件生成的默认(有效)命令

cl test.cpp MyClass.cpp
如果在命令行中键入,将导致完全相同的错误

还有其他方法可以从build命令中删除它,如“从项目中排除文件”,可以在解决方案资源管理器的右键单击菜单中找到,但这会降低编辑/导航到的便利性。将其正确标记为头文件将为您提供调试期间Intellisense自动完成、转到定义和源代码视图的最佳体验。

因为您包含了MyClass.cpp,它本身不是编译单元,而是头文件。确保Visual Studio被告知不要尝试单独构建它,默认情况下,它假定
.h
文件是头文件,
.cpp
都是单独编译的单元

访问项目属性并将“项目类型”从“C/C++编译器”更改为“C/C++头”

这将有效地将build命令更改为工作版本

cl test.cpp
通过添加所有文件生成的默认(有效)命令

cl test.cpp MyClass.cpp
如果在命令行中键入,将导致完全相同的错误


还有其他方法可以从build命令中删除它,如“从项目中排除文件”,可以在解决方案资源管理器的右键单击菜单中找到,但这会降低编辑/导航到的便利性。将其正确标记为头文件将为您提供调试期间Intellisense自动完成、转到定义和源代码视图的最佳体验。

模板定义必须位于.h文件中,并且您不应包含.cpp文件。@latedeveloper:这是约定,不是需要。@JohnB:不是事实,而是约定。IDE后面的约定,例如,“应该”=约定。事实仍然是,《公约》存在。我想这就是我们双方的意思。模板定义必须在.h文件中,并且您不应该包含.cpp文件。@latedeveloper:这是约定,不是需要。@JohnB:不是事实,而是约定。IDE后面的约定,例如,“应该”=约定。事实仍然是,《公约》存在。我想这就是我们俩的意思。
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)" (??0?$MyClass@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@@QAE@XZ) referenced in function _main
Error   LNK2019 unresolved external symbol "public: __thiscall MyClass<int>::MyClass<int>(void)" (??0?$MyClass@H@@QAE@XZ) referenced in function _main
Error   LNK2019 unresolved external symbol "public: void __thiscall MyClass<int>::setItem(int const &)" (?setItem@?$MyClass@H@@QAEXABH@Z) referenced in function _main
cl test.cpp
cl test.cpp MyClass.cpp