C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

passing a template function to qsort

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Andrey
Guest





PostPosted: Fri Dec 12, 2003 9:34 am    Post subject: passing a template function to qsort Reply with quote



Hi all,

aCC returns "Unsatisfied symbols: compare(const void *,const void *)",
when I compile code that uses this SortObjects function.

template <class T>
void SortObjects(int numObjects, T* objects)
{

qsort(objects, numObjects, sizeof(T), (int(*)(const void *, const
void *)) compare<T>);

}

compare is declared and defined like this just above the SortObjects
definition.

template <class T>
int compare(const void* one, const void* another)
{

if (*((T*)one) > *((T*)another))
{

return 1;

}
else if (*((T*)one) < *((T*)another))
{

return -1;

}
else
{

return 0;

}

}

The same code compiles fine on g++.

Am I missing some compiler flags or this cannot be done on aCC at all?



Thanks in advance,

Andrey

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Dhruv
Guest





PostPosted: Fri Dec 12, 2003 6:21 pm    Post subject: Re: passing a template function to qsort Reply with quote



On Fri, 12 Dec 2003 04:34:59 -0500, Andrey wrote:

Quote:
Hi all,

aCC returns "Unsatisfied symbols: compare(const void *,const void *)",
when I compile code that uses this SortObjects function.

template <class T
void SortObjects(int numObjects, T* objects)
{

qsort(objects, numObjects, sizeof(T), (int(*)(const void *, const
void *)) compare
}

compare is declared and defined like this just above the SortObjects
definition.

template int compare(const void* one, const void* another)
{

I *think* this is where your problem lies... You can only pass functions
with c linkage to qsort, and template functions cannot have c linkage, so,
you will have to use some other strategy here...


Regards,
-Dhruv.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Roger Orr
Guest





PostPosted: Sat Dec 13, 2003 2:27 am    Post subject: Re: passing a template function to qsort Reply with quote



"Andrey" <ae5880 (AT) yahoo (DOT) com> wrote

Quote:
Hi all,

aCC returns "Unsatisfied symbols: compare(const void *,const void *)",
when I compile code that uses this SortObjects function.

template <class T
void SortObjects(int numObjects, T* objects)
{

qsort(objects, numObjects, sizeof(T), (int(*)(const void *, const
void *)) compare

I'd recommend you take a look at using the standard library 'sort' function
rather than trying to fit your C++ code into using C runtime functions.

Roger Orr
--
MVP in C++ at www.brainbench.com



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Michael Tiomkin
Guest





PostPosted: Sat Dec 13, 2003 2:35 am    Post subject: Re: passing a template function to qsort Reply with quote

[email]ae5880 (AT) yahoo (DOT) com[/email] (Andrey) wrote in message news:<395332d2.0312111330.7c9449a4 (AT) posting (DOT) google.com>...
Quote:
Hi all,

aCC returns "Unsatisfied symbols: compare(const void *,const void *)",
when I compile code that uses this SortObjects function.

template <class T
void SortObjects(int numObjects, T* objects)
{

qsort(objects, numObjects, sizeof(T), (int(*)(const void *, const
void *)) compare
}

compare is declared and defined like this just above the SortObjects
definition.

This compare should be a C function for qsort. You can add the
'extern "C"' attribute to the function, but in this case you wouldn't
be able to use this template more than once in the same compilation
unit: the C objects cannot use name mangling, and only one object
with the same name will be allowed. You'd better use std::sort instead.

Quote:
template <class T
int compare(const void* one, const void* another)
{

if (*((T*)one) > *((T*)another))
{

return 1;

}
else if (*((T*)one) < *((T*)another))
{

return -1;

}
else
{

return 0;

}

}

The same code compiles fine on g++.

Am I missing some compiler flags or this cannot be done on aCC at all?

This cannot be done safely on most C++/C compilers.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Sat Dec 13, 2003 2:37 am    Post subject: Re: passing a template function to qsort Reply with quote

Dhruv wrote:
Quote:

I *think* this is where your problem lies... You can only pass functions
with c linkage to qsort, and template functions cannot have c linkage, so,
you will have to use some other strategy here...


The C++ standard library provides two versions of qsort. One takes a
pointer to a function with C linkage and the other takes a pointer to a
function with C++ linkage. Same thing for bsearch.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Dietmar Kuehl
Guest





PostPosted: Sat Dec 13, 2003 11:13 am    Post subject: Re: passing a template function to qsort Reply with quote

[email]ae5880 (AT) yahoo (DOT) com[/email] (Andrey) wrote:
Quote:
template <class T
void SortObjects(int numObjects, T* objects)
{
qsort(objects, numObjects, sizeof(T), (int(*)(const void *, const
void *)) compare }

You probably wanted to write

std::sort(objects, objects + numObjects);

It is not only easier to use but normally also faster than 'qsort()'. Also,
it operates on any assignable type, not just on PODs...

Quote:
template <class T
int compare(const void* one, const void* another)
{
if (*((T*)one) > *((T*)another))
{
return 1;
}
else if (*((T*)one) < *((T*)another))
{
return -1;
}
else
{
return 0;
}
}

For a function to be a viable argument to the standard C function taking
function pointer arguments, it has to be declared as 'extern "C"'. However,
I think you cannot declare templates as 'extern "C"'. BTW, you should not
cast away constness unless you have a very good reason to do so. The above
code should probably look more like this:

if (*static_cast ...

Quote:
The same code compiles fine on g++.
Am I missing some compiler flags or this cannot be done on aCC at all?

This forum is concerned with standard C++, not with the details of any
attempt to implement this standard. In standard C++ the above code is not
required to work. The simple work-around is the use 'std::sort()' instead
of 'std::qsort()'.
--
<mailto:dietmar_kuehl (AT) yahoo (DOT) com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Pete Becker
Guest





PostPosted: Sat Dec 13, 2003 3:43 pm    Post subject: Re: passing a template function to qsort Reply with quote

Dietmar Kuehl wrote:
Quote:


For a function to be a viable argument to the standard C function taking
function pointer arguments, it has to be declared as 'extern "C"'.

It can also be extern "C++". 25.4/4.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.