473,327 Members | 2,012 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

Template functions questions

I'm trying to avoid (or at least, minimize) duplicity of effort. I have
the following function:

void Permissions::Exists(const unsigned int id,
std::vector<Permission>::const_iterator& iter)
{
if (m_permissions.empty())
iter = m_permissions.end() ;

std::vector<Permission>::const_iterator cit=m_permissions.begin();

for (cit; cit != m_permissions.end(); cit++)
{
if (cit->Id() == id)
break ;
}
iter = cit ;
}
It can take the ff combinations of args:

string, iter
string, const_iter
unsigned int, iter
unsigned int, const_iter
The logic is essentially the same for all cases - I would like to write
this as a template function, like:

template < class T1, class T2)
void Permissions::Exists(T1 key, T2 iterator_type)
I have the ff questions:

1). I don't ever recall seeing an iterator being passed as template
parameter (although I can't see why not - since it has a type) - is it
legal to use an iterator as a 'type' in a template func?
2). It appears like I may have to use template specialization (because I
am looking at different fields when doing the 'key comparison' - in
which case, my idea to use templates as "shorthand" (or as a compile
time code generator), is invalidated because I will still have to write
4 specializations ... am I thinking along the right lines, or am I
missing something (i.e. can I implement the above function as ONE
template function instead of four)?

3). last but not the least - a general template programming question
relating to 'const correctness' - is passing a const variable to a
template func treated as a different type from a non-const - i.e. if I
have the ff:

template <class T>
T foo(T var);

If I pass a const int variable to the function, and then in another part
of the code, pass a non-const int to the foo function - will the
compiler generate code for the two "functions"

const int foo(const int);
int foo(int);

(probably an ill posed question - but I hope you understand what I'm
getting at)


Jun 19 '07 #1
6 1708
Bartholomew Simpson wrote:
....
1). I don't ever recall seeing an iterator being passed as template
parameter (although I can't see why not - since it has a type) - is it
legal to use an iterator as a 'type' in a template func?
Any type may me used in a template as long as it conforms to the usage,
2). It appears like I may have to use template specialization (because I
am looking at different fields when doing the 'key comparison' - in
which case, my idea to use templates as "shorthand" (or as a compile
time code generator), is invalidated because I will still have to write
4 specializations ... am I thinking along the right lines, or am I
missing something (i.e. can I implement the above function as ONE
template function instead of four)?
Think of a parameter that may mean you don't need to specialize.
>
3). last but not the least - a general template programming question
relating to 'const correctness' - is passing a const variable to a
template func treated as a different type from a non-const - i.e. if I
have the ff:

template <class T>
T foo(T var);

If I pass a const int variable to the function, and then in another part
of the code, pass a non-const int to the foo function - will the
compiler generate code for the two "functions"

const int foo(const int);
int foo(int);
In general, pass a const reference for input parameters and whatever
makes sense for output parameters.

template <typename Key, typename Getter>
std::vector<Permission>::const_iterator
Permissions::Exists(const Key & id, const Getter &, getter)
{
std::vector<Permission>::const_iterator cit=m_permissions.begin();

for (cit; cit != m_permissions.end(); cit++)
{
if (cit->*Getter() == id)
return cit;
}
return m_permissions.end();
}

obj.Exists( 3, & Permission::Id );

Or, you can work it to have a syntax like:

obj.Exists<& Permission::Id>( 3 );

Either way, it makes little difference although the compiler may have an
easier time optimizing "obj.Exists<& Permission::Id>( 3 )".
Jun 19 '07 #2
Bartholomew Simpson a écrit :
I'm trying to avoid (or at least, minimize) duplicity of effort. I have
the following function:

void Permissions::Exists(const unsigned int id,
std::vector<Permission>::const_iterator& iter)
{
What is m_permissions ? a globale ?
if (m_permissions.empty())
iter = m_permissions.end() ;

std::vector<Permission>::const_iterator cit=m_permissions.begin();

for (cit; cit != m_permissions.end(); cit++)
{
if (cit->Id() == id)
break ;
}
iter = cit ;
}
It can take the ff combinations of args:

string, iter
string, const_iter
unsigned int, iter
unsigned int, const_iter
The logic is essentially the same for all cases - I would like to write
this as a template function, like:

template < class T1, class T2)
void Permissions::Exists(T1 key, T2 iterator_type)
I have the ff questions:

1). I don't ever recall seeing an iterator being passed as template
parameter (although I can't see why not - since it has a type) - is it
legal to use an iterator as a 'type' in a template func?
STL is full of it.
You should even pass start and end of search as paremeter.
template <class InputIterator>
void Permissions::Exists(const unsigned int id,InputIterator& iter,
InputIterator& start, InputIterator& end);

An even better altenative would be to use the std::find_if algorithm.

struct Permissions::cmp_id :
std::binary_function<Permission,unsigned int,bool>
{
bool operator()(const Permission& perm, unsigned int id)
{
return perm.Id()==id;
}
};

vector<Permission>::iterator iter=find_if(start,end,
bind2nd(Permissions::cmp_id(), id));

Michael
Jun 19 '07 #3


Gianni Mariani wrote:
>
template <typename Key, typename Getter>
std::vector<Permission>::const_iterator
Permissions::Exists(const Key & id, const Getter &, getter)
Is this correct?. What data type is the argument 'getter' ?

Lastly, the return type of the Exist() method as you have implemented
it, is a const_iterator - which may not always be appropriate. the
function is a utility function that is called by many other methods. I
may (for example), want to delete an item if it exists - in which case,
a const iterator is no good to me. This is why I wanted to 'templatize'
the iterator - because sometimes I want a non-const iterator (for when I
want to delete the found item), and other times, the const iterator is
ok, if I just need to verify that the item exists. Since C++ dosen't
allow function overloading based on return types alone, I had to pass
the iterator as a function argument.

So the correct signature should return a void and take an iterator type
as an input/output arg. The question remains - can I 'templatize' such a
function?
{
std::vector<Permission>::const_iterator cit=m_permissions.begin();

for (cit; cit != m_permissions.end(); cit++)
{
if (cit->*Getter() == id)
return cit;
}
return m_permissions.end();
}

obj.Exists( 3, & Permission::Id );

Or, you can work it to have a syntax like:

obj.Exists<& Permission::Id>( 3 );

Either way, it makes little difference although the compiler may have an
easier time optimizing "obj.Exists<& Permission::Id>( 3 )".
Jun 19 '07 #4


Michael DOUBEZ wrote:
Bartholomew Simpson a écrit :
>I'm trying to avoid (or at least, minimize) duplicity of effort. I
have the following function:

void Permissions::Exists(const unsigned int id,
std::vector<Permission>::const_iterator& iter)
{


What is m_permissions ? a globale ?
A static member variable

Jun 19 '07 #5
Bartholomew Simpson wrote:
I'm trying to avoid (or at least, minimize) duplicity of effort. I have
the following function:

void Permissions::Exists(const unsigned int id,
std::vector<Permission>::const_iterator& iter)
{
if (m_permissions.empty())
iter = m_permissions.end() ;

std::vector<Permission>::const_iterator cit=m_permissions.begin();

for (cit; cit != m_permissions.end(); cit++)
{
if (cit->Id() == id)
break ;
}
iter = cit ;
}
It can take the ff combinations of args:

string, iter
string, const_iter
unsigned int, iter
unsigned int, const_iter
The logic is essentially the same for all cases - I would like to write
this as a template function, like:

template < class T1, class T2)
void Permissions::Exists(T1 key, T2 iterator_type)
I have the ff questions:

1). I don't ever recall seeing an iterator being passed as template
parameter (although I can't see why not - since it has a type) - is it
legal to use an iterator as a 'type' in a template func?
Yes. It happens all the time. Have a look at the stuff provided by
<algorithm>. Most standard algorithms take iterator arguments. The iterator
type is then used as a template parameter.

2). It appears like I may have to use template specialization (because I
am looking at different fields when doing the 'key comparison' - in
which case, my idea to use templates as "shorthand" (or as a compile
time code generator), is invalidated because I will still have to write
4 specializations ... am I thinking along the right lines, or am I
missing something (i.e. can I implement the above function as ONE
template function instead of four)?
Depends. You might be able to minimize the code that needs to be specialized
by turning it into an accessor function that can be passed to other
functions as a function object parameter.

3). last but not the least - a general template programming question
relating to 'const correctness' - is passing a const variable to a
template func treated as a different type from a non-const - i.e. if I
have the ff:

template <class T>
T foo(T var);

If I pass a const int variable to the function, and then in another part
of the code, pass a non-const int to the foo function - will the
compiler generate code for the two "functions"

const int foo(const int);
int foo(int);
No. But that is nothing about templates. It just happens that

void f ( int i );

and

void f ( int const i );

are treated as identical function signatures. Think about it: would you
expect

void f ( int const param ) {}
...
int i = 5;
f(i);

to give a compiler error? After all, the variable i is passed by value and
the value 5 is about as const as it gets.
The difference between const and non-const only kicks in when you are
dealing with references. In that case, templates will also see the
difference:
typedef void (*f_ptr) ( void );

template < typename T>
void f ( void ) {}

template < typename T >
f_ptr g ( T t ) {
return ( &f<T);
}

template < typename T >
f_ptr h ( T & t ) {
return ( &f<T);
}

int main ( void ) {
int i = 0;
int const ci = 0;
{
bool no_distinction = ( g(i) == g(ci) );
if ( no_distinction ) {
std::cout << "one function generated\n";
} else {
std::cout << "two fucntions generated\n";
}
}
{
bool no_distinction = ( h(i) == h(ci) );
if ( no_distinction ) {
std::cout << "one function generated\n";
} else {
std::cout << "two fucntions generated\n";
}
}
}


Best

Kai-Uwe Bux
Jun 19 '07 #6
Bartholomew Simpson wrote:
>

Gianni Mariani wrote:
>>
template <typename Key, typename Getter>
std::vector<Permission>::const_iterator
Permissions::Exists(const Key & id, const Getter &, getter)

Is this correct?. What data type is the argument 'getter' ?
Try it and see.
>
Lastly, the return type of the Exist() method as you have implemented
it, is a const_iterator - which may not always be appropriate.

Maybe a const and non const methods would be better.

....
So the correct signature should return a void and take an iterator type
as an input/output arg. The question remains - can I 'templatize' such a
function?
Returning a void is not always the best way.
Jun 19 '07 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Colin Mc Mahon | last post by:
Hi all, I am currently using a system you are probably familiar with if you have done any templating with vbscript, define a template file with special tokens in it(like ##Content## etc), load...
2
by: CoolPint | last post by:
As a self-exercise, I am trying to write a generic Priority Queue, which would store any type and and accept any user-definable "priority" function. After much tinkering, I came up with...
15
by: iuweriur | last post by:
A few questions on the curiously recurring template pattern: This page: http://c2.com/cgi/wiki?CuriouslyRecurringTemplate this part: template<typename T> struct ArithmeticType { T operator...
5
by: Ruben Campos | last post by:
Some questions about this code: template <typename T> class MyTemplate; template <typename T> MyTemplate <T> operator- (const MyTemplate <T> & object); template <typename T> MyTemplate <T>...
9
by: Jon Wilson | last post by:
I have a class which needs to accumulate data. The way we get this data is by calling a member function which returns float on a number of different objects of different type (they are all the...
5
by: Steve | last post by:
Hi, Does C++ allow the programmer to declare a template with in a template so that a generic function can instantiate the embedded template? For example, could code such as this exist: ...
3
by: Hamilton Woods | last post by:
Diehards, I developed a template matrix class back around 1992 using Borland C++ 4.5 (ancestor of C++ Builder) and haven't touched it until a few days ago. I pulled it from the freezer and...
5
by: Hong Ye | last post by:
Traits is a useful template technique to simplfy the implementation of some classes. however, I met some questions when I tried to understand and implement it. Following is an example of traits...
3
by: Thomas Pajor | last post by:
Hey everybody, I got into serious trouble with template programming. I have a class which uses three template arguments, say template<typename Atype, typename Btype, typename Ctype> class...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.