简体   繁体   English

符号未找到C ++打印向量控制台

[英]Symbol not found C++ printing vectors to console

I'm relatively new to C++, and currently working on an assignment using vectors and ostream to print out a vector which contains other vectors inside. 我对C ++比较陌生,目前正在使用向量和ostream进行分配,打印出一个包含其他向量的向量。 However I am currently getting this error when I try to run the program: symbol not found 但是,当我尝试运行程序时,我当前收到此错误: symbol not found

operator<<(std::basic_ostream<char, std::char_traits<char> >&, Hash_Table<Entry, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)", referenced from: _main in main.o

here is my main() code 这是我的main()代码

int main(){

Hash_Table<Entry,string> newTable(11);


// insert
Entry newEntry;
newEntry.setKey("cat");
newTable.insert(newEntry);

//print Dictionary
cout << "Dictionary contains:";
cout << newTable;

cout << '\n';

    return 0;
}

here is my Entry class: 这是我的Entry课程:

class Entry {
public:
Entry();
string getKey();
void setKey(string key);
int getHash(int M);
friend istream& operator>> (istream& in, Entry& right);
friend ostream& operator<< (ostream& out, const Entry& right);

private:

string data;
};

Here is my Hash_Table class: 这是我的Hash_Table类:

template <typename T,typename K>
class Hash_Table {
public:
Hash_Table(int size); 
void insert(T newEntry); 
T* search(K key); 
void delete_entry(T* entry);
friend ostream& operator<< (ostream& out, const Hash_Table& right);
private:
vector< vector<T> > hashTable;
};

And lastly here is my function to print the vector.... 最后这是我打印矢量的功能....

template <typename T,typename K>
ostream& operator<< (ostream& out, const Hash_Table<T,K>& right) {
for (int i=0; i < right.hashTable.size(); i++)
    for (int j=0; j < right.hashTable[i].size(); j++) 
        out << "Slot " << i << ", Entry " << j
        << "\n" << right.hashTable[i][j] << "\n\n";
return out;
}

Basically I am attempting to implement a Dictionary (ADT). 基本上我试图实现一个字典(ADT)。 The hash table is a vector of vectors... so far everything seems to work... however I cant get it to print the contents of the vector out to the console. 哈希表是向量的向量...到目前为止,一切似乎都有效......但是我无法将它的内容打印到控制台。 I should be about to print out a vector with cout << newTable; 我应该打算用cout << newTable;打印出一个矢量cout << newTable; .... but I keep getting this error. ....但我一直收到这个错误。 From what I understand, my printing function should work... am I overlooking something?? 从我的理解,我的打印功能应该工作......我是否忽略了什么?

However I am currently getting this error when I try to run the program: symbol not found 但是,当我尝试运行程序时,我当前收到此错误: symbol not found

I guess by "running" you mean compiling, because this is a compiler error, not a runtime error. 我想通过“运行”你的意思是编译,因为这是编译器错误,而不是运行时错误。

The problem is propbably that you defined your operator<< in a .cpp file, so that it is not visible to the compiler. 问题可能是您在.cpp文件中定义了operator<< ,因此编译器看不到它。 With normal classes and functions, that's ok, but with templates it is not, as the compiler needs to see the template definition whe you intantiate the template. 使用普通的类和函数,没关系,但是模板不是这样,因为编译器需要在模板定义时查看模板。

The solution would be to put the operator definition in the header that defines the Hash_Table class template. 解决方案是将运算符定义放在定义Hash_Table类模板的标头中。 You will probably run into similar errors regarding the member functions of Hash_Table . 您可能会遇到有关Hash_Table的成员函数的类似错误。

Another problem is, as noted by Yuushi, the templated operator declared a friend of the class. 另一个问题是,如Yuushi所指出的,模板化运算符宣布了该类的朋友。 It's a matter of taste, but I usually refrain completely from declaring friend functions if there is another solution, and there is: 这是一个品味问题,但如果有另一个解决方案,我通常会完全避免宣布朋友功能,并且:

template <typename T, typename K>
class Hash_Table {
    //....

  void printToStream(std::ostream& os) const {
    //your output algorithm here
  }
};

template <class T, class K>
std::ostream& operator<<(std::ostream& os Hash_Table<T,K> const& ht) {
  ht.printToStream(os);
  return os;
}

It's normally considered bad design to declare friends, because it partly breaks encapsulation and is an even tighter coupling than inheritance. 通常认为声明朋友的设计不好,因为它部分地打破了封装,并且是一种比继承更紧密的耦合。 While it's mostly a matter of taste when friends' convenience surpasses the tight coupling for normal functions, it is a huge encapsulation issue when dealing with templates, because anyone can specialize the template: 虽然当朋友的便利性超过正常功能的紧密耦合时,这主要是一种品味问题,但在处理模板时这是一个巨大的封装问题,因为任何人都可以专门化模板:

template <> istream& operator>> <int, std::string> (istream& in, const Hash_Table<int,std::string>& right) 
{
  right.hashTable.resize(1);
  for (unsigned i = 0; i < 2000000; ++i)
    right.hashTable[0].push_back("I just hijacked your Hash_Table implementation!";
} 

This is evil but legal - you made that function your friend, although it might not be so friendly ;-) 这是邪恶但合法的 - 你把这个功能变成了你的朋友,虽然它可能不那么友好;-)

This is part of the annoyance of templates and friend functions. 这是模板和friend功能烦恼的一部分。 When you declare that you're writing a friend function within a template class, the compiler does not actually recognise that the friend function itself is a template. 当您声明在模板类中编写友元函数时,编译器实际上并不认识到friend函数本身就是模板。 One way of fixing this is to use member templates: 解决此问题的一种方法是使用成员模板:

template <typename T, typename K>
class Hash_Table
{
    //....

    template <typename T2, typename K2>
    friend ostream& operator<< (ostream& out, const Hash_Table<T2, K2>& right);
};

Then in the definition: 然后在定义中:

template <typename T, typename K>
ostream& operator<<(ostream& out, const Hash_Table<T, K>& f)
{
    //Code as before
}   

For more information, see here , although be warned, it may make your head hurt a bit. 有关更多信息,请参阅此处 ,虽然会收到警告,但可能会让您头疼一些。

Change your Hash_Table class: 更改您的Hash_Table类:

template< typename T, typename K>
class Hash_Table;   // fore declaration

template< typename T, typename K>
ostream&  operaotr<< (ostream& out, Hash_Table<T,K> const& right); //foreward declaration

template <typename T,typename K>
class Hash_Table {
public:
Hash_Table(int size); 
void insert(T newEntry); 
T* search(K key); 
void delete_entry(T* entry);
// change here!!!
friend ostream& operator<< <T,K> (ostream& out, const Hash_Table& right);
private:
vector< vector<T> > hashTable;
};

the implementation if operator<< remains to be your original code. 如果operator <<仍然是您的原始代码,则执行该实现。 Try it ,and see if there's any more error. 试一试,看看是否还有错误。

Let me talk a little about the friend of a class template. 我来谈谈一个类模板的朋友。 A friend of a class template can be classified into three kinds: 类模板的朋友可以分为三种:

  1. Normal class and normal function, no any template 普通类和普通函数,没有任何模板
  2. Class template and Function template 类模板和函数模板
  3. Specialized class template and specialized function template 专业类模板和专用功能模板

There're some examples to make it clear: 有一些例子可以说清楚:

template<typename T>
class Exam
{
   friend void normalFunc();
   friend class NormalClass;
};
// nothing happen, it looks straightforward

Another example: 另一个例子:

template<typename T>
class TemplateClass;
template<typename T>
void FunctionTemplate();

template<typename T>
class Exam
{
    template<typename U>
    friend class TemplateClass; 
    template<typename U>
    friend void FunctionTemplate();
};

This means all of the instances of the function template "FunctionTemplate" and the class template "TemplateClass" are the friend of all of the instances of the class template "Exam" Means that: 这意味着函数模板“FunctionTemplate”的所有实例和类模板“TemplateClass”都是类模板“Exam”的所有实例的朋友意味着:

  1. TemplateClass<AnyType> is friend class of Exam<AnyOtherType> TemplateClass<AnyType>Exam<AnyOtherType>朋友类

  2. FunctionTemplate<AnyType> is friend function of Exam<AnyOtherType> FunctionTemplate<AnyType>Exam<AnyOtherType>友元函数

Notes that, AnyType can be the same as AnyOtherType. 注意,AnyType可以与AnyOtherType相同。

Here's the most useful example, this is what you want: 这是最有用的例子,这就是你想要的:

    template<typename T>
    class TemplateClass;
    template<typename T>
    void FunctionTemplate();

    template<typename T>
    class Exam
    {

        friend class TemplateClass<T>; 

        friend void FunctionTemplate<T>();
    };

This means that: 这意味着:

  1. Only the TemplateClass<SpecificType> is friend class of Exam<SpecificType> 只有TemplateClass<SpecificType>Exam<SpecificType>友元类
  2. Only the FunctionTemplate<SpecificType> is friend function of Exam<SpecificType> 只有FunctionTemplate<SpecificType>Exam<SpecificType>友元函数

By this way, you can grant the friend access priviledge more pricisely and of course more safely! 通过这种方式,您可以更加谨慎地授予朋友访问权限,当然更安全!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM