-
September 6th, 2011, 07:13 AM
#1
Library and Template Trouble
Hi all,
I am trying to implement a generic smart pointer library which links to another main program. To make the smart pointer library generic I am using a template with a typename called "type". However, when I attempt to link my library to the main program and compile them both, I get a compiler error which says something like "Expected type, got link" (where "link" is a class in the main program).
I was wondering why this is happening and what I can do to fix it. I've tried passing my smart_pointer an "int" type and this works fine.
For example:
smart_pointer<int> p = new int(); // Works okay!
However...
smart_pointer<link> l = new link(); // Does not work! (Compiler: "Expected type, got link")
I've included my code below (not all of it, but just the parts I think are relevant). Also, I'm not supposed to alter the main program in any way (just my library).
Any help would be greatly appreciated.
Thanks.
EDIT: Please refer to the code on the third post below this one.
Last edited by ace_of_pentacles; September 6th, 2011 at 09:16 PM.
Reason: Updating inadequate code.
-
September 6th, 2011, 09:26 AM
#2
Re: Library and Template Trouble
I suppose I'll first give the obligatory "there are perfectly good smart pointer libraries available, why are you reinventing the wheel" response. It looks like this is probably homework, but someone was going to say it so why not me?
That done, it would be most helpful if you gave us the exact error message and indicate the line in your code that generates it. (The line number can sometimes be hard to find in template errors. There will probably be one pointing somewhere in smart_pointer, and one pointing somewhere in main(). Both will be useful.)
-
September 6th, 2011, 10:25 AM
#3
Re: Library and Template Trouble
"link" wouldn't happen to actually be a template class by any chance...?
Your code (once stripped of un-useable code) compiles fine, so you are keeping something from us.
Please post the minimal but full and exact code that recreates this. Code tags ([CODE][/CODE]) would be a plus.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 6th, 2011, 09:10 PM
#4
Re: Library and Template Trouble
Sorry for my previous inadequacies.
I have stripped down the code to be as small as possible yet still generate the error in question.
So, I have these two files "test.h" (library) and "test_main.c" (main program). When I try to compile these two files using:
Code:
g++ test_main.c -o test_main
I get the following error:
Code:
test_main.c: In function ‘int main(int, char**)’:
test_main.c:14:22: error: type/value mismatch at argument 1 in template parameter list for ‘template<class type> class smart_pointers::smart_pointer’
test_main.c:14:22: error: expected a type, got ‘link’
test_main.c:14:26: error: invalid type in declaration before ‘=’ token
test_main.c:14:32: error: expected type-specifier before ‘link’
test_main.c:14:32: error: invalid conversion from ‘int*’ to ‘int’
test_main.c:14:32: error: expected ‘,’ or ‘;’ before ‘link’
test_main.c:15:5: error: base operand of ‘->’ is not a pointer
test_main.c:16:20: error: base operand of ‘->’ is not a pointer
Why is this happening? When I rename all instances of "link" in test_main.c it compiles fine... But I need the program to work without changing the test_main.c file.
Here is my code:
test.h
Code:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
namespace smart_pointers{
using namespace std;
template<typename type>
class smart_pointer{
public:
type *pdata;
smart_pointer(){
pdata = NULL;
}
smart_pointer(type *dat){
pdata = dat;
}
type *operator->(){
return pdata;
}
};
}
test_main.c
Code:
#include "test.h"
using namespace smart_pointers;
class link
{
public:
smart_pointer<link>next;
int data;
};
int main(int argc, char*argv[])
{
smart_pointer<link> l = new link();
l->data = 5;
printf("%d\n", l->data);
}
Thank your for your time.
-
September 6th, 2011, 09:55 PM
#5
Re: Library and Template Trouble
Originally Posted by ace_of_pentacles
Why is this happening? When I rename all instances of "link" in test_main.c it compiles fine... But I need the program to work without changing the test_main.c file.
It sounds like a name collision issue. I tested your code with g++ 4.4.5, and indeed I faced the same problem. Commenting out the #include <iostream> removed the problem. (In the example you really do not need any of the headers; the header you do need is <cstddef> for NULL, and then <cstdio> in test_main.c, which would be better named test_main.cpp.) A better way to handle this would be to use your own namespace, e.g.,:
Code:
namespace aop
{
class link
{
public:
smart_pointer<link>next;
int data;
};
}
int main(int argc, char* argv[])
{
smart_pointer<aop::link> l = new aop::link();
l->data = 5;
printf("%d\n", l->data);
}
By the way, do not use using directives at namespace scope in header files.
Last edited by laserlight; September 6th, 2011 at 09:58 PM.
-
September 7th, 2011, 07:03 AM
#6
Re: Library and Template Trouble
I didn't reproduce the error with using MinGW with your exact code, however, I get the exact same diagnostic with this:
Code:
using namespace std;
template <typename>
class some_template
{
};
namespace std
{int a = 5;}
class a
{
};
int main()
{
some_template<a>;
}
My guess is that somewhere inside the iostream is an object called link (possibly inside namespace std, but I cannot be sure). Both are allowed to coexist (one is a type, the other is an instance). The problem is that the template decided to resolve to the link value, rather than your user supplied link type.
You can solve this by prefixing your link to specify you want the globally defined one:
Code:
using namespace std;
template <typename>
class some_template
{
};
namespace std
{int a = 5;}
class a
{
};
int main()
{
some_template< ::a>; //Watch the space! <:: is a keyword...
}
However... This will only work if the instance "link" was first defined in namespace std.
To add to laserlight's suggestion though, I'd recommend not using "using namespace std" either. The amount of collisions it provides usually isn't worth it (IMO)
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 7th, 2011, 11:14 AM
#7
Re: Library and Template Trouble
If indeed there is a link object in namespace std, then the solution is to drop the "using namespace std;" line and instead make individual statements like
using std::cout;
using std::endl;
etc.
-
September 7th, 2011, 11:52 AM
#8
Re: Library and Template Trouble
Originally Posted by Lindley
If indeed there is a link object in namespace std...
Wouldn't that be a violation of the standard though? Is the implementation allowed to add things to namespace std that is not referenced in the standard and not prefixed by _? Or is it just bad practice?
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
September 7th, 2011, 12:04 PM
#9
Re: Library and Template Trouble
Originally Posted by Lindley
If indeed there is a link object in namespace std
I did not check, but I think link refers to the function of that name from <unistd.h>, which may have been included in <iostream>. If my guess is correct then link would be in the global namespace. My hunch is based on the fact that when I commented out the using directive for namespace std, my attempted compile still failed.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|