Thread: Scope resolution problems using a template

  1. #1
    Registered User
    Join Date
    Dec 2004
    Posts
    3

    Scope resolution problems using a template

    I'm trying to write a program to build a BST from a file, using a template because there's more than one file type.


    My first question is: How do I forward declare a pointer to a template class before I know what type it has to be? I've tried using a function (DetermineType returns an int that IDs the data type) and then declaring a pointer and pointing it to new memory of the type yielded by the function, but I think the pointer is going out of scope (?) or something?

    Code:
    		cout << "Enter the name of the file you wish to open, including extension." << endl
    			 << "(C:\\, etc) ";
    
    		cin.getline(File, 50, '\n');
    
    		ifstream fin;
    
    		fin.open(File);
    
    		if(!fin)
    		{
    			cout << "Error opening file. Make sure the file exists and is not in use. ";
    			break;
    		}
    
    		string entry;
    		fin >> entry;
    		fin.close();
    
    		int TreeType = DetermineType(entry);
    
    		if (TreeType == 1)//int
    		{
    			BinarySearchTree<int> * x;
    
    			x = new BinarySearchTree<int>(NULL);
    		}
    		else if (TreeType == 2)//char
    		{
    			BinarySearchTree<char> * x;
    
    			x = new BinarySearchTree<char>(NULL);
    		}
    		else if (TreeType == 3)//double
    		{
    			BinarySearchTree<double> * x;
    
    			x = new BinarySearchTree<double>(NULL);
    		}
    		else if (TreeType == 4)//string
    		{
    			BinarySearchTree<string> * x;
    
    			x = new BinarySearchTree<string>(NULL);
    		}

    A similar problem occurs when I try to read in data from a file...I get error C2065 on the line with "fin >> fileEntry;", then the same error again on the line with "x -> insert(fileEntry);"

    Code:
    		//while there is more of the file to read,
    		//read in entries and add them to the BST
    		while(!EOF)
    		{
    			if (TreeType == 1)
    			{
    				int fileEntry;
    			}
    			else if (TreeType == 2)
    			{
    				char fileEntry;
    			}
    			else if (TreeType == 3)
    			{
    				double fileEntry;
    			}
    			else if (TreeType == 4)
    			{
    				string fileEntry;
    			}
    
    			fin >> fileEntry;//C2065 fileEntry undeclared
    
    			x -> insert(fileEntry);//C2065 x undeclared
    
    		}

    can anyone help?

    I'm using Visual Studio .NET 7.1.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    When you declare a variable within a block (such as an if statement), it exists only within that block. The following won't work because x doesn't exist outside of the if block:
    Code:
    if (true) {
      int x = 10;
    }
    cout<< x <<endl;
    >while(!EOF)
    This is useless. EOF is a macro value, not a magic word that returns true if the stream that you happen to be working with has reached end-of-file.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Dec 2004
    Posts
    3
    Thanks for your reply. I'll redo the entry-reading part...and I guess my method of choosing pointer type will not work, at least not in the way I'm trying to do it.

    That takes me back a step to the problem I was hoping to solve: How to declare the type of a pointer to template class without knowing the data type. Is that even possible? I've been looking for resources on that, but I can't find anything. Is the only way to do it to determine the type, then execute all the code in the "if" block?

    Thanks again for your time.

  4. #4
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    This sounds like a good use for polymorphism:
    Code:
    class object;
    class int_object: public object;
    class double_object: public object;
    class char_object: public object;
    class string_object: public object;
    
    ...
    
    BinarySearchTree<object*> *x = new BinarySearchTree<object*>(0);
    
    ...
    
    object *fileEntry;
    
    switch (TreeType) {
      case 1: fileEntry = new int_object; break;
      case 2: fileEntry = new char_object; break;
      case 3: fileEntry = new double_object; break;
      case 4: fileEntry = new string_object; break;
    }
    
    while (fin>> fileEntry)
      x->insert(fileEntry);
    My best code is written with the delete key.

  5. #5
    Registered User
    Join Date
    Jun 2004
    Posts
    722
    If you want to know the type, I'd advise like this
    Code:
    template<class Type>
    class BinaryTree{
    public:
    static const int typeid;
    ...
    }
    Then some specializations, when definiting typeid.
    Code:
    const int  BinaryTree<int>::typeid = 1;
    const int  BinaryTree<char>::typeid = 2;
    const int  BinaryTree<double>::typeid = 3;
    const int  BinaryTree<std::string>::typeid = 4;
    //any other types not defined in previous specializations
    template<class GeneralType>const int  BinaryTree<GeneralType>::typeid = 0;
    I've never tried this, nor even compiled. Tell me if it works
    But like Prelude showed, I think polymorphism would be better.
    Last edited by xErath; 12-05-2004 at 03:18 PM.

  6. #6
    Registered User
    Join Date
    Dec 2004
    Posts
    3
    The second method gives a bunch of errors like C2838, "illegal qualified name in member declaration" and C2086, redefinition of type_id (used instead of typeid because that's actually listed as an operator). Is this the result of declaring it in the class? Where else would/could it go?

    The first method has an error on the "fin >> newEntry" line, saying the >> operator isn't defined for right-hand operand of type 'object *'. What's the best way around this, defining the >> and << operators, or somehow returning a value of int/char/double/string instead?

    While I remember it, are there any compilers more "template-friendly" than VS.NET 7.1? I've read somewhere before that there are some errors it gives that are unfounded, like C2664, which I've had a lot of trouble with as well: "cannot convert parameter 1 from int/double/char to object * const with Type = object *". The error isn't just from use of object *, I've gotten it with other templates in other situations and none of the fixes I've seen seem to work.

    Sorry for being such a noob, and thanks for all your help guys ;[

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >What's the best way around this, defining the >> and << operators
    Yes. Generally, when you write a class that needs to be input from a file or standard input, you'll be overloading both the << and >> operators. I made that assumption when suggesting the solution.

    >are there any compilers more "template-friendly" than VS.NET 7.1?
    As far as I know, the only compiler the conforms properly to the standard for templates is the Comeau compiler. However, unless you do weird stuff, Visual Studio .NET 2003 and later will be more than enough.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 05-29-2005, 10:06 AM
  2. Syntax problems with Class Template
    By cuddlez.ini in forum C++ Programming
    Replies: 3
    Last Post: 12-05-2004, 07:25 PM
  3. Template question
    By grscot in forum C++ Programming
    Replies: 1
    Last Post: 04-29-2003, 03:12 PM
  4. quick question about scope resolution
    By *ClownPimp* in forum C++ Programming
    Replies: 8
    Last Post: 11-03-2002, 10:04 PM
  5. Returning references (scope problems?)
    By DarkDragon in forum C++ Programming
    Replies: 3
    Last Post: 12-23-2001, 07:48 PM