我有三个文件.main.cpp的内容是
#include<iostream>
#include<QString>
#include "util.h"
int main()
{
using Util::convert2QString;
using namespace std;
int n =22;
QString tmp = convert2QString<int>(n);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
util.h
namespace Util
{
template<class T>
QString convert2QString(T type , int digits=0);
}
Run Code Online (Sandbox Code Playgroud)
util.cpp
namespace Util
{
template<class T>
QString convert2QString(T type, int digits=0)
{
using std::string;
string temp = (boost::format("%1%") % type).str();
return QString::fromStdString(temp);
}
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用以下命令编译这些文件时,我得到未定义的引用错误
vickey@tb:~/work/trash/template$ g++ main.cpp util.cpp -lQtGui -lQtCore -I. -I/usr/local/Trolltech/Qt-4.8.0/include/QtCore -I/usr/local/Trolltech/Qt-4.8.0/include/QtGui -I/usr/local/Trolltech/Qt-4.8.0/include
/tmp/cca9oU6Q.o: In function `main':
main.cpp:(.text+0x22): undefined reference to `QString …Run Code Online (Sandbox Code Playgroud) 我在从模板类创建类对象时遇到问题,在模板类中我需要构造函数也是模板并在创建对象时接受参数.但是,当我尝试创建对象时,我收到一条错误消息,指出我引用了一些不存在的内容.
这是我的代码:
using namespace std;
#include <cstdlib>
template <class Node_Type>
class BinaryTree
{
public:
BinaryTree(Node_Type);
BinaryTree(Node_Type, Node_Type);
BinaryTree(Node_Type, Node_Type, Node_Type);
bool isEmpty();
Node_Type info();
Node_Type inOrder();
Node_Type preOrder();
Node_Type postOrder();
private:
struct Tree_Node
{
Node_Type Node_Info;
BinaryTree<Node_Type> *left;
BinaryTree<Node_Type> *right;
};
Tree_Node *root;
};
#endif
Run Code Online (Sandbox Code Playgroud)
和我的.cpp:
template <class Node_Type>
BinaryTree<Node_Type>::BinaryTree(Node_Type rootNode) {
root = rootNode;
root->left = NULL;
root->right = NULL;
}
Run Code Online (Sandbox Code Playgroud)
.cpp还有更多,但它只是其他功能成员无关紧要.我上面显示的构造函数是我无法工作的.
在我的主要内容中,我试图通过调用声明我的对象:
BinaryTree<char> node('a');
Run Code Online (Sandbox Code Playgroud)
但是当我尝试这个时,我收到一条错误消息,指出:
undefined reference to `BinaryTree<char>::BinaryTree(char)'
Run Code Online (Sandbox Code Playgroud)
我一直试图解决这个问题两天了.我用Google搜索了我能想到的每个主题,并在Stack Overflow和其他来源上阅读了无数的例子,没有任何帮助.谁能解释一下我的问题是什么?我知道如何完成我的项目,如果语法在C++中不那么荒谬,我现在就完成了.提前致谢!
将源文件用于基于模板的类(STL和boost)以及将实现放入标头似乎是一种常见的惯例.我假设与头文件和源文件中的声明和实现之间的经典分离相比,这将增加编译包含头文件的源文件所需的时间.这样做的原因可能是因为您必须告诉源文件中的编译器使用哪些模板,这可能会导致文件膨胀.a文件.
假设链接器在库增长时也需要更多时间,那么编译包含库头的源文件所需的时间会更快?
1.不使用.cpp文件并将整个类(包括实现)放入标头中
//foo.hpp
template <class T>
class Foo
{
public:
Foo(){};
T bar()
{
T* t = NULL;
//do stuff
return *t;
}
};
Run Code Online (Sandbox Code Playgroud)
要么
2.在库本身的源文件中显式编译各种类型的模板
//foo.h
template <class T>
class Foo
{
public:
Foo(){};
T bar();
};
//foo.cpp
template <class T>
T Foo<T>::bar()
{
T* t = NULL;
//do stuff
return *t;
}
template class Foo<int>;
template class Foo<float>;
template class Foo<double>;
template class Foo<long long>;
Run Code Online (Sandbox Code Playgroud) c++ templates header compilation-time explicit-instantiation
注意:几个相关问题(例如,这个问题)最终被标记为该问题的重复项。我知道这个特定问题并遵循相应答案中的解决方案。然而,不同的编译器会产生不同的行为,我不知道为什么。
我的库具有一个类模板,我想为库中的某些模板参数提供实例,因为该模板需要一些重要的编译时间。类模板可能如下所示 ( stack.hpp)
#ifndef MY_STACK
#define MY_STACK
template<class T>
class stack
{
public:
stack();
};
#endif
Run Code Online (Sandbox Code Playgroud)
其实现驻留在相应的stack.tpp文件中
#ifndef MY_STACK_TPP
#define MY_STACK_TPP
#include <iostream>
template<class T>
stack<T>::stack()
{
std::cout << "My stack constructor!" << std::endl;
}
#endif
Run Code Online (Sandbox Code Playgroud)
由于我只想提供对某些模板参数的支持,因此我stack.cpp创建了以下显式模板实例:
#include "stack.hpp"
template class stack<double>;
template class stack<char>;
#include "stack.tpp"
Run Code Online (Sandbox Code Playgroud)
它使用 g++ 和 clang++ 进行编译,但生成的共享库的符号存在差异:
g++ -std=c++11 -c stack.cpp -o stack.so
nm -C stack.so | grep stack
0000000000000049 t _GLOBAL__sub_I_stack.cpp
0000000000000000 W …Run Code Online (Sandbox Code Playgroud) 我的模板类 Queue 有问题,我一直在实现文件中实现这些函数,所以我看到了这个答案并决定在头文件中进行实现:
队列文件
#ifndef QUEUE_HPP
#define QUEUE_HPP
#include "Instruction.hpp"
#include "MicroblazeInstruction.hpp"
#include <memory>
#include <list>
template<typename T>
class Queue{
public:
Queue(unsigned int max): maxSize{max} {};
~Queue();
std::list<T> getQueue(){
return queue;
};
void push(T obj){
if(queue.size() < maxSize){
queue.push_front(obj);
}
else{
queue.pop_back();
queue.push_front(obj);
}
};
private:
Queue(const Queue&);
Queue& operator=(const Queue&);
unsigned int maxSize;
std::list<T> queue;
};
#endif
Run Code Online (Sandbox Code Playgroud)
我从我的主要调用这个函数:
#include "icm/icmCpuManager.hpp"
#include "Instruction.hpp"
#include "MicroblazeInstruction.hpp"
#include "CpuManager.hpp"
#include "File.hpp"
#include "Utils.hpp"
#include "MbInstructionDecode.hpp"
#include "Queue.hpp"
#include "PatternDetector.hpp"
#include …Run Code Online (Sandbox Code Playgroud)