473,666 Members | 2,093 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Mixing STL maps/vectors with templates

5 New Member
This is a really annoying thing to look up in Google because all pages that mention STL maps or vectors will most likely also contain the word "template". So maybe this question has been asked before, but it's nearly impossible to find.

I'm having trouble using STL vectors, maps, ... in templated functions, when the templated class is a template parameter of the map too.
Below is a (cannibalized) example of a class 'Model' which contains several STL maps with different objects. I want to perform a similar operation on these different maps. Instead of writing nearly similar methods for each type of map, it would be much nicer to have a single template method. In the example below, the findStuff method returns a pointer to the object to be found, or NULL if it can't be found. This is of course rather useless because I could just use find() directly, but it's just an illustration.
Aside from having to add the 'typename' word which I'm not familiar with, the code compiles fine until I try to use findStuff, like:
Expand|Select|Wrap|Line Numbers
  1. string sName("someGroup");
  2. Group *theGroup = findStuff( sName, m_mGroups );
This produces a linking error in GCC (4.1.1):
undefined reference to `Group* Model::findStuf f<Group>(std::b asic_string<cha r, std::char_trait s<char>, std::allocator< char> > const&, std::map<std::b asic_string<cha r, std::char_trait s<char>, std::allocator< char> > const, Group, std::less<std:: basic_string<ch ar, std::char_trait s<char>, std::allocator< char> > const>, std::allocator< std:: pair<std::basic _string<char, std::char_trait s<char>, std::allocator< char> > const, Group> > >&)'

I'm not too familiar with templates, so maybe I'm just making a silly error? However, it appears the template is correctly instantiated, only it can't be found by the linker?

Expand|Select|Wrap|Line Numbers
  1. /* Class code */
  2. Class Model
  3. {
  4. public:
  5.   map<const string, Group> m_mGroups;
  6.   map<const string, Shape> m_mShapes;
  7.  
  8.   template <class T>
  9.   T * findStuff( const string &sName, map<const string, T> &mMap );
  10. };
  11.  
  12. template <class T>
  13. T * Model::findStuff( const string &sName, map<const string, T> &mMap )
  14. {
  15.     typename map<const string, T>::iterator it = mMap.find(sName);
  16.     if( it == mMap.end() )
  17.         return NULL;
  18.     return &(it->second);
  19. }
Feb 9 '07 #1
5 1777
AdrianH
1,251 Recognized Expert Top Contributor
Hi,

I'm sorry, but I'm not sure what you are trying to do. The code is incomplete (i.e. not compliable) and I don't have time to figure out what you are attempting. Oh, wait a minute, perhaps you were trying to do this?

Expand|Select|Wrap|Line Numbers
  1. #include "stdafx.h"
  2.  
  3. #include <string>
  4. #include <map>
  5. using namespace std;
  6.  
  7. struct Group{};
  8. struct Shape{};
  9.  
  10. class Model
  11. {
  12. public:
  13.   map<const string, Group> m_mGroups;
  14.   map<const string, Shape> m_mShapes;
  15.  
  16.   template <class T>
  17.   T * findStuff( const string &sName, map<const string, T> &mMap );
  18.     void fn()
  19.     {
  20.         string sName("someGroup");
  21.         Group *theGroup = findStuff( sName, m_mGroups );
  22.     }
  23. };
  24.  
  25. template <class T>
  26. T * Model::findStuff( const string &sName, map<const string, T> &mMap )
  27. {
  28.     typename map<const string, T>::iterator it = mMap.find(sName);
  29.     if( it == mMap.end() )
  30.         return NULL;
  31.     return &(it->second);
  32. }
  33.  
  34. int main(int argc, char* argv[])
  35. {
  36.     Model a;
  37.     a.fn();
  38.     return 0;
  39. }
  40.  
This compiled and linked correctly (although there were lots of warning about identifiers being truncated due to being longer than 255 characters, but this is normal and can be ignored for the most part).

If this is what you are attempting, then I don't see why it doesn't link on your system. If it is not, please post a minimal, but compliable set of code so that it can be independently verified and tested and I will see what I can do.


Adrian
Feb 9 '07 #2
DrLex
5 New Member
Hi,

I'm sorry, but I'm not sure what you are trying to do. The code is incomplete (i.e. not compliable) and I don't have time to figure out what you are attempting. Oh, wait a minute, perhaps you were trying to do this?
Yes, that's roughly what I try to do, except that findStuff() would be called in a derived class of Model. The funny thing is that your code compiles on my system as well. So I did some more tests and it appears that the linking error occurs as soon as I put the definition of findStuff in a different file than the one in which it is called. For instance:
File "model.h":
Expand|Select|Wrap|Line Numbers
  1. #ifndef MODEL_H
  2. #define MODEL_H
  3.  
  4. #include <map>
  5. #include <string>
  6. using namespace std;
  7.  
  8. struct Group{};
  9.  
  10. class Model
  11. {
  12. public:
  13.     map<const string, Group> m_mGroups;
  14.  
  15.     template <class T>
  16.     T * findStuff( const string &sName, map<const string, T> &mMap );
  17.     void fn()
  18.     {
  19.         string sName("someGroup");
  20.         Group *theGroup = findStuff( sName, m_mGroups );
  21.     }
  22. };
  23.  
  24. #endif // MODEL_H
File "model.cpp" :
Expand|Select|Wrap|Line Numbers
  1. #include "model.h"
  2.  
  3. template <class T>
  4. T * Model::findStuff( const string &sName, map<const string, T> &mMap )
  5. {
  6.     typename map<const string, T>::iterator it = mMap.find(sName);
  7.     if( it == mMap.end() )
  8.         return NULL;
  9.     return &(it->second);
  10. }
File "main.cpp":
Expand|Select|Wrap|Line Numbers
  1. #include "model.h"
  2.  
  3. int main(int argc, char* argv[])
  4. {
  5.     Model a;
  6.     a.fn();
  7.     return 0;
  8. }
If I would define findStuff() in model.h, it works. But that's no solution in my case because I'd like to use it in a derived class of Model. And I simply want to know why it doesn't work of course :)
Feb 9 '07 #3
mambazo
1 New Member
You should read this:

http://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.h tml

Most of what is said applies to Visual Studio and other popular C++ compilers. Basically, the bottom line is that you _have_ to put the templated definitions in your header file, so that the entire definition is available at instantiation.

Also, I don't see why this is a problem if you want to call the function from a derived class.
Feb 9 '07 #4
DrLex
5 New Member
Most of what is said applies to Visual Studio and other popular C++ compilers. Basically, the bottom line is that you _have_ to put the templated definitions in your header file, so that the entire definition is available at instantiation.
OK, it's not a nice & clean solution, but it works. Thanks for pointing this out.

Also, I don't see why this is a problem if you want to call the function from a derived class.
This is indeed not a problem, my assumption that the definition must be in the very same file as where the method is called, was wrong (luckily).
Feb 9 '07 #5
AdrianH
1,251 Recognized Expert Top Contributor
Most of what is said applies to Visual Studio and other popular C++ compilers. Basically, the bottom line is that you _have_ to put the templated definitions in your header file, so that the entire definition is available at instantiation.
Yeah, this is a limitation of most C++ compilers. I don't know of one that actually allows you to do it any other way. It has to do with the format of the object files generated. They aren't able to store the necessary information. Sorta the same with inlining, though I think that compilers are starting to do a better job about that without having to put the inlined code available to everyone.


Adrian
Feb 11 '07 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

10
15826
by: Michael Aramini | last post by:
I need to represent 1D and 2D arrays of numeric or bool types in a C++ program. The sizes of the arrays in my intended application are dynamic in the sense that they are not known at compile time, so I'd like to use an STL container class template such as valarray or vector to represent 1D arrays, and valarrays or vectors of valarrays or vectors to represent 2D arrays. As I said the sizes of the arrays in my intended application are...
12
1652
by: Fred Ma | last post by:
Hello, I was looking at Meyers's "Effective STL", item 23 about choosing between vectors and maps (at least that the choice for me). In many cases, using sorted vectors is faster for lookups. The two reasons are (1) that vector elements are smaller, since map elements need at least 3 pointers, and (2) contiguity of vector elements in memory ensure fewer page faults.
19
1941
by: nick | last post by:
The attached program is fine, but I need to create vectors for each AcctExample object. I know that I can do the following: vector<AcctExample> example which makes a vector of AcctExample objects called example. Now, how do I activate the methods for each object? Also, why are we replacing templates with vectors? (That was what the assignment required. I don't get why we do this). ACCTEXAMPLE.CPP #include <conio.h>
5
1545
by: roberts.noah | last post by:
It is my understanding that if you contain vectors or maps you don't need to create copy constructors because the default calls that constructor. It is my understanding that if you use these types you don't have to worry about them at all...even if the contents of your map or vector may contain other maps or vectors. Am I mistaken in any way? We are running into a very strange bug that is avoiding detection by hiding in the default...
10
1882
by: ballpointpenthief | last post by:
How good is the C language for implementing maps, filters and accumulators? SCHEME programmers would be able to pass procedures as arguments quite easily, whereas C programmers would - I guess - have use variadic function pointers which is frankly disgusting, and I'm not even sure I want to sit down and hack at the language in that way. Your thoughts? Any libraries you could refer me to?
3
4698
by: frank | last post by:
Hi I've got aplication, which one is written in unmanaged c++ with stl, i've made for it gui in managed c++. Problem becomes when I'm starting to filling up for example datagrids, when I'm adding row to datagrid , some varibles (vectors etc) in unmanaged class are cleared or filled with null. I want mention also when i compile only unmanaged class for console project (without .net gui) problem never happends, everything works fine.
5
1883
by: pallav | last post by:
I have a map like this: typedef boost::shared_ptr<NodeNodePtr; typedef std::vector<NodePtrNodeVecPtr; typedef std::map<std::string, NodePtrNodeMap; typedef std::map<std:string, NodePtr>::iterator NodeMapItr; NodeMap nmap; In my classes, I often find myself copying the second arguments of
3
6462
by: jacek.dziedzic | last post by:
Hi! What is the canonical way of finding an intersection of two std::maps? i.e. I have std::map<whatever,size_tmap1; std::map<whatever,size_tmap2; .... and I need an std::vector containing all the values that occur
1
2058
by: Rob | last post by:
How would I do this? I want to be able to handle vectors of many different types of data and vectors that can contain any number of other vectors of data. Currently, I have a templated function that handles vectors of vectors of <typename T(which could be anything from int to vectors of something else). As well, I have specialized/overloaded functions to handle the single-level vectors of data (e.g. vector<string>). So the templated...
0
8444
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8869
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8781
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8639
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7386
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5664
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4198
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
2011
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1775
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.