Solved

Correct template class forward declaration

Posted on 2001-07-29
18
926 Views
Last Modified: 2012-06-22
I know there's a method for doing forward declaration for template classes in the cpp file, but I don't remember what was the correct method.

template<class T>
class foo
{
public:
T x;
};

How do I get a forward declaration of the above template for foo<int>??=9673F
0
Comment
Question by:Zulma9999
  • 8
  • 5
  • 3
  • +1
18 Comments
 
LVL 6

Expert Comment

by:thienpnguyen
ID: 6331266

// forward declare
template<class T>
class foo;


template<class T>
class bar
{
public:
     T x;
     foo<int> *f;
};

template<class T>
class foo
{
public:
     T x;
     bar<T> *b;
};

0
 

Author Comment

by:Zulma9999
ID: 6331303
I'm sorry thienpnguyen, but that's not what I'm talking about.

Let me be more specific.

//I have this in foo.h file
template<class T>
class foo
{
public:
 T FunctionXYZ(T xyz);
T x;
};

//I have this in the foo.cpp file
template<class T>
T foo::FunctionXYZ(T xyz)
{
 return xyz + xyz;
}


With the above coode, how would I do a forward declaration of foo<int> inside the foo.cpp file.
There's a forward declaration method that allows you to use foo<int> in another cpp file when you have the template function code in the cpp file instead of the header file.
I'm looking for that method.
0
 
LVL 6

Expert Comment

by:thienpnguyen
ID: 6331324
when you  implement template, you have to put
"class's declare and  class's implement" in same
header file. You can not have separate to header .h
and .cpp . Look at some stl template source code,
you will see that point.
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 22

Expert Comment

by:nietod
ID: 6331374
>> when you  implement template, you have to put
>> "class's declare and  class's implement" in same
>> header file.

That is not true.  You can use the export keyword to define a exported  template.  From the C++ standard 14.7

An  exported  template
  need  only  be declared (and not necessarily defined) in a translation
  unit in which it is instantiated.  A template function  declared  both
  exported and inline is just inline and not exported.


For example

//I have this in foo.h file
export template<class T>  // NOTE "export".
class foo
{
   public:
   T FunctionXYZ(T xyz);
   T x;
};

//I have this in the foo.cpp file
template<class T>
T foo::FunctionXYZ(T xyz)
{
   return xyz + xyz;
}

HOWEVER, making this work (for the compiler) is not an easy thing, so not all compilers currretly support it.  howevr it is part of the offical C++ standard langauge.
0
 

Author Comment

by:Zulma9999
ID: 6331387
Sorry, but this is not what I'm looking for.
I'm looking for a method that will work with Visual C++.
Your method will not work with VC++
0
 
LVL 30

Expert Comment

by:Axter
ID: 6331410
Try modifying your code to the following:

//I have this in the foo.cpp file
template<class T>
T foo<T>::FunctionXYZ(T xyz)
{
  return xyz + xyz;
}

0
 
LVL 22

Expert Comment

by:nietod
ID: 6331423
>> I'm looking for a method that will work with Visual C++.
>> Your method will not work with VC++
You never mentioned that in your question.   How were we to know that.

The method I showed you is 100% legal C++  It is the only way to do it.

You asked

"I know there's a method for doing forward declaration"

What i showed you is THE method.  There is no other method.  That method is completely legal C++.  The fact that you are using a compiler that doesn't yet support it is out of our control--especially if you don't tell us that.
0
 

Author Comment

by:Zulma9999
ID: 6331459
I didn't know that the compiler was going to be an issue, or I would have provided that information.

>>That method is completely legal C++.
I don't care if it's legal.  If I can't use it then it's worthless to me.

If you can't provide me with a work solution, then I'll wait for some other expert to help me.
0
 

Author Comment

by:Zulma9999
ID: 6331463
Axter,
I tried your method, and it does let me compile the code, but it fails when linking.
I get this error

error LNK2001: unresolved external symbol "public: int __thiscall foo<int>::FunctionXYZ(int)" (?FunctionXYZ@?$foo@H@@QAEHH@Z)

Any ideas?
0
 

Author Comment

by:Zulma9999
ID: 6331465
thienpnguyen,
>> when you  implement template, you have to put
>> "class's declare and  class's implement" in same
>> header file.

I know that there is a way to do this by putting a specific declaration in the cpp file of the template.  The declaration is specific to the class used for T
0
 
LVL 30

Accepted Solution

by:
Axter earned 200 total points
ID: 6331486
Try the following in your foo.cpp file

template foo<int>;

Example:
//I have this in the foo.cpp file
#include "foo.h"

template foo<int>;

template<class T>
T foo<T>::FunctionXYZ(T xyz)
{
 return xyz + xyz;
}
0
 
LVL 22

Expert Comment

by:nietod
ID: 6331541
>> If you can't provide me with a work solution, then I'll wait for some other expert to help me.
You will wait forever.  This is the only way to do it and it is not jey supported by VC.

>>  it fails when linking.I get this error
This will be a problem.

Vc does not support exported templates.  All the tempalte code that Vc generates will have internal linkage.  There is no way to tel the VC compiler to generate template code with external linkage.  So there is no way for tempalte code in one translation unit to satisfy imported tempalte code from another translation unit.

I'm not making this up or anything.  I told you about this at the start when I said

>>  not all compilers currretly support
>> it.  howevr it is part of the offical C++ standard langauge.

>> I know that there is a way to do this by putting a specific declaration in the cpp file
YES,.   I told you what this is.  but VC doesn't support it.

You know that it can be done.  You don't know that VC supports it right?  Well it doesn't.  There are MS knowlegebase articles about the fact that it doesn't support it.
0
 
LVL 22

Expert Comment

by:nietod
ID: 6331555
From the MS knowledgebase
********************************************************************
PRB: LNK2001 on Template Member Functions

--------------------------------------------------------------------------------
The information in this article applies to:

Microsoft Visual C++, 32-bit Enterprise Edition, versions 5.0, 6.0
Microsoft Visual C++, 32-bit Professional Edition, versions 5.0, 6.0
Microsoft Visual C++, 32-bit Learning Edition, version 6.0

--------------------------------------------------------------------------------


SYMPTOMS
You receive a LNK2001 error message on template member functions unless the member functions are also defined in the same translation unit.



CAUSE
The compiler does not support the use of the "export" keyword as specified in the C++ standard below:

Section 14
Para# 7: Declaring a class template exported is equivalent to declaring all of its non-inline function members, static data members, member classes, member class templates and non-inline function member templates which are defined in that translation unit exported.

Para# 8: Templates defined in an unnamed namespace shall not be exported. A template shall be exported only once in a program. An implementation is not required to diagnose a violation of this rule. A non-exported template that is neither explicitly specialized nor explicitly instantiated must be defined in every translation unit in which it is implicitly instantiated (temp.inst) or explicitly instantiated (temp.explicit); no diagnostic is required. An exported template need only be declared (and not necessarily defined) in a translation unit in which it is instantiated. A template function declared both exported and inline is just inline and not exported.



RESOLUTION
You have the following two options:

Keep the template declaration and definition together in one translation unit.


If you know in advance how your template class will be used in your application, you can perform explicit instantiation for the template class.

For example, for class MyStack declared in Myprog.h
template <class T> MyStack;
and implemented in Myprog.cpp, the following explicitly instantiates MyStack for int variables:
template class MyStack<int>;






MORE INFORMATION
Explicit instantiation allows you to create an instantiation of a template class or function without actually using it in your code. The idea is to explicitly instantiate all possible types for the template class in the implementation file. Thus, when the .cpp file is compiled, the code is generated for these instantiations, alleviating the LNK2001 error.

Please refer to the Visual C++ Help for more information regarding explicit instantiation.



REFERENCES
For additional information, click the article number below to view the article in the Microsoft Knowledge Base:

Q128789 BUG: LNK2001 on Member Function When Use Nested Class Template

Additional query words:

Keywords : kbLangCPP kbLinker kbVC kbVC500 kbVC600 kbDSupport
Issue type : kbprb
Technology : kbVCsearch kbAudDeveloper kbVC32bitSearch kbVCPE500 kbVCPE600 kbVCEE500 kbVCEE600 kbVCLE600
 


Last Reviewed: May 5, 2001
? 2001 Microsoft Corporation. All rights reserved. Terms of Use.
 

0
 

Author Comment

by:Zulma9999
ID: 6331601
Axter,
I just tried it out, and it works.
I knew it could be done.  I just couldn't remember how.

I was starting to believe the other expert.

Thanks a lot.  You're a lifesaver.
0
 

Author Comment

by:Zulma9999
ID: 6331606
nietod,
If you haven't read Axter's comment, you can do this in VC++ by doing this "template foo<int>"

Thanks for trying anyway.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6331653
FYI Zulma9999,
You do realize that the method I posted requires you to make this type of declaration for each type you use the foo class with.

0
 
LVL 22

Expert Comment

by:nietod
ID: 6331972
>> f you haven't read Axter's comment, you can do this in VC++ by doing this "template foo<int>"
And that then works for all template instanciations?    Nope.

Now try instiation your class for type char.  it doesn't work.

Read the knowledgabe article I posted.  it suggests this as a workaroud, but only for the case where you know in advance exaclly what template parameters the class will be instanciated for.   You don't know that.  Or if you do know that, it was not presented in your question.
0
 

Author Comment

by:Zulma9999
ID: 6333947
>>You do realize that the method I posted requires you to
>>make this type of declaration for each type you use the
>>foo class with.
Yes, I know this already.  I have my reasons for wanting the function code in the cpp file only.  And it is worth the extra maintenance required to update the file for every new type I want to use.

>>And that then works for all template instanciations?    
>>Nope.
This will work for all templates.

>>Now try instiation your class for type char.  it doesn't
>>work.
I just tried it with char, and it works.  I'm not sure what you're trying to get at.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

813 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now