Visual Studio 10上的C++编译错误
C++ compile error on Visual Studio 10
我在使用Visual Studio编译这个简单程序时遇到以下错误:
error LNK2019: unresolved external symbol "public: void __thiscall CoList<int>::enqueue(int)" (?enqueue@?$CoList@H@@QAEXH@Z) referenced in function _main
error LNK2019: unresolved external symbol "public: virtual __thiscall CoList<int>::~CoList<int>(void)" (??1?$CoList@H@@UAE@XZ) referenced in function _main
error LNK2019: unresolved external symbol "public: int __thiscall CoList<int>::dequeue(void)" (?dequeue@?$CoList@H@@QAEHXZ) referenced in function _main
error LNK2019: unresolved external symbol "public: int __thiscall CoList<int>::count(void)" (?count@?$CoList@H@@QAEHXZ) referenced in function _main
error LNK2019: unresolved external symbol "public: __thiscall CoList<int>::CoList<int>(void)" (??0?$CoList@H@@QAE@XZ) referenced in function _main
error LNK1120: 5 unresolved externals
我的程序很简单。我不使用外部库,只使用"iostream"answers"exception"标头。。。这是完整的代码:
CoList.h
#pragma once
#include "CoListItem.h"
template <class T>
class CoList
{
public:
CoList();
virtual ~CoList();
void enqueue(T value);
T dequeue();
T *peek();
int count();
private:
CoListItem<T> *m_root;
int m_count;
};
CoListItem.h
#pragma once
template <class T>
class CoListItem
{
public:
CoListItem();
virtual ~CoListItem();
T value;
CoListItem *next;
};
CoList.cpp
#include "CoList.h"
#include <exception>
template <class T>
CoList<T>::CoList()
{
}
template <class T>
CoList<T>::~CoList()
{
}
template <class T>
void CoList<T>::enqueue(T value)
{
if (this->m_root != NULL) {
this->m_root = new CoListItem<T>();
this->m_root->value = value;
this->m_root->next = NULL;
} else {
CoListItem<T> *tempitem = new CoListItem<T>();
tempitem->value = value;
tempitem->next = this->m_root;
this->m_root = tempitem;
}
this->m_count++;
}
template <class T>
T CoList<T>::dequeue()
{
if (this->m_root == NULL) {
throw std::exception();
} else {
T retval = this->m_root->value;
CoListItem *next = this->m_root->next;
delete this->m_root;
this->m_root = next;
return retval;
}
}
template <class T>
T *CoList<T>::peek()
{
if (this->m_root == NULL) {
return NULL;
} else {
return *this->dequeue();
}
}
template <class T>
int CoList<T>::count()
{
return this->m_count;
}
CoListItem.cpp
#include "CoListItem.h"
template <class T>
CoListItem<T>::CoListItem()
{
}
template <class T>
CoListItem<T>::~CoListItem()
{
}
最后是主要功能:
#include <iostream>
#include "CoList.h"
#include "CoListItem.h"
using namespace std;
int main(int argc, char *argv[])
{
CoList<int> list;
for(int i = 0; i < 10; i++)
list.enqueue(i);
cout << "Count: " << list.count() << endl;
for(int i = 0; i < 10; i++)
cout << "Item: " << list.dequeue() << endl;
cout << "Count: " << list.count() << endl;
int wait = 0;
cin >> wait;
}
正如您所看到的,这是一个使用链表的非常简单的队列实现。。。
函数模板的定义(包括类模板的成员函数(必须在.h文件中,以便它们出现在使用它们的每个cpp文件中。模板就是这样工作的。不能将定义放入cpp文件中。从技术上讲,有一个export
关键字可以实现这一点,但由于几乎没有任何实现支持它,它在新标准中被删除了。
阅读:包含模型
template
定义应该对使用它的代码可见
- 将所有定义放在".h"文件中
- 将定义放在".cpp"文件中(用于代码分离(,然后
#include
那个".cpp"文件
例如,在您的情况下,您可以使用#include "CoList.cpp"
而不是"CoList.h"
。等等。
考虑一个模板函数,它取T并执行模数(%(,或者执行一个简单的加法(+(。
template <class T>
T GetT(T t1, T t2)
{
return t1%t2;
}
您可以在该代码中看到"无错误"。好吧当我通过两个int时,它被编译:
GetT(10,20);
但是当我通过float/double时,WONT编译:
GetT(10.6, 20.5);
编译器将发出:error C2296: '%' : illegal, left operand has type 'double'
和其他相关错误。关键是,只有为特定的数据类型实例化模板代码至少一次,才能编译模板代码。模板代码是垃圾代码——编译器不关心代码中的实际内容。在您的情况下,CPP只是一个编译器忽略的文本文件-全部。
话虽如此,当我使用运算符+
而不是运算符%
时,它将适用于所有基本数据类型,但不适用于缺少operator +
的类。在这种情况下,编译器将再次编译该数据类型(类(的模板。
在某些情况下,当编译器和链接器发现某些代码是重复的,并且对于所有/几种数据类型都是相同的时,它们会协同工作以减少最终二进制代码的大小。但情况不同。
这直接来自Nicolai Josutis的传奇书籍
C++模板:完整指南
模板编译两次:
- 在没有实例化的情况下,会检查模板本身的语法是否正确,这里会发现分号等语法错误
- 在实例化时,会检查模板代码以确保所有调用都是有效的。发现无效调用,例如不受支持的函数调用
这导致了模板实践处理中的一个重要问题。当函数模板以触发实例化的方式使用时,编译器将(在某个时候(需要查看该模板定义。当函数的声明足以编译其用途时,这打破了函数通常的编译和链接区别。
因此,对于模板,声明和定义应该保存在同一个头文件中,以便在使用它们的每个cpp中都可见。
- std::is_base_of表示ctor编译错误
- Qt5:使用QCommandLineParser类时出现奇怪的编译错误
- 如何修复sfml c++代码编译错误
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- vscode下的Arduino代码出现意外编译错误
- 第三方 API 中的编译错误 - Visual Studio
- std::cout输出int时出现编译错误
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 提升图广度优先搜索前置编译错误
- C++ 中的编译错误:未定义对"主"的引用 collect2:错误:ld 返回 1 个退出状态
- 使用带有 ref 参数的成员函数创建线程时出现编译错误
- 我在C++中遇到了这个奇怪的编译错误
- 在C++中使用 Catch 测试框架编译错误"error: expected ';' at end of declaration list"
- 使用 std::enable_if 限制派生类的模板参数时出现编译错误
- 现代OpenGL和GLEW Libraray的编译错误
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- C ++程序编译错误,找不到/访问文件
- 使用直接大括号初始化时,C++ 编译错误"声明末尾的预期";"
- 为什么传递非静态成员函数会导致编译错误?