Help Please: Making a function template accept a default argument

C

CoolPint

Can anyone explain how I can make the following function accept an
default arguement for the last parameter, which should be an optional
functor?

template <typename T, typename FUNCTOR>
void bsort(T * si, T * ei, FUNCTOR cmpfunc)
{
int k = 0;
for (T * i = si; i < ei - 1; i++, k++)
for (T * j = si; j < (ei-k-1) ; j++)
if ( cmpfunc(*j, *(j+1)) )
swap(*j, *(j+1));
}

Let's say I want to make bsort accept either two or three arguements,
the last
one being optional one which determines the sorting order.
I have tested that overloading the template with another template like
this
template <typename T> void bsort(T *si, T * ei); works! But,

But I am wondering if I can achieve the same effect by providing the
default arguement rather than overloading?
For example, I could define a functor which can be used as the default
argument like below:

template <typename T>
class AscOrder {
public:
bool operator() (T a, T b)
{ return (a >= b ? true : false); }
};

I thought then I could use it as the default argument for the last
parameter like below:
template <typename T, typename FUNCTOR>
void bsort(T *si, T *ei, FUNCTOR cmpfunc = AscOrder<T>() );

But it doesn't work like I thought! The following function call
double dArray[] = {0.5,0.142,0.9,1.5,2.23,2.19,3.5,0.04};
bsort (dArray, dArray+8);
generates compiler error message saying "no matching function for
call..."

What I am misunderstanding here? I would very appreciate if anyone
could kindly explain what I am doing wrong and how I might fix. I just
created this simple self-exercise to help me learn the features of
templates and functors, not to learn how to sort so please no advise
on sorting algorithms. TIA!
 
V

Victor Bazarov

CoolPint said:
Can anyone explain how I can make the following function accept an
default arguement for the last parameter, which should be an optional
functor?

template <typename T, typename FUNCTOR>
void bsort(T * si, T * ei, FUNCTOR cmpfunc)
{
int k = 0;
for (T * i = si; i < ei - 1; i++, k++)
for (T * j = si; j < (ei-k-1) ; j++)
if ( cmpfunc(*j, *(j+1)) )
swap(*j, *(j+1));
}

Let's say I want to make bsort accept either two or three arguements,
the last
one being optional one which determines the sorting order.
I have tested that overloading the template with another template like
this
template <typename T> void bsort(T *si, T * ei); works! But,

But I am wondering if I can achieve the same effect by providing the
default arguement rather than overloading?
For example, I could define a functor which can be used as the default
argument like below:

template <typename T>
class AscOrder {
public:
bool operator() (T a, T b)
{ return (a >= b ? true : false); }
};

I thought then I could use it as the default argument for the last
parameter like below:
template <typename T, typename FUNCTOR>
void bsort(T *si, T *ei, FUNCTOR cmpfunc = AscOrder<T>() );

But it doesn't work like I thought! The following function call
double dArray[] = {0.5,0.142,0.9,1.5,2.23,2.19,3.5,0.04};
bsort (dArray, dArray+8);
generates compiler error message saying "no matching function for
call..."

That's perfectly normal. Types (in your case 'FUNCTOR') cannot
be deduced from the default function arguments (14.8.2.4/17).
What I am misunderstanding here? I would very appreciate if anyone
could kindly explain what I am doing wrong and how I might fix. I just
created this simple self-exercise to help me learn the features of
templates and functors, not to learn how to sort so please no advise
on sorting algorithms. TIA!

There is a simple fix. Provide another function (overloaded) with
only two arguments and call your function with what you want:

template<class T> void bsort(T t1, T t2) {
bsort(t1, t2, AscOrder<T>()); // calls the 3-argument variation
}

Victor
 
C

CoolPint

That's perfectly normal. Types (in your case 'FUNCTOR') cannot
be deduced from the default function arguments (14.8.2.4/17).

Could you kindly elaborate a little more as to why Types cannot be
deduced
from the default function arguments? Is it because an instantion is
required
at the time of declaration to do so? Is it related to why we cannot
have default arguments for function template type parameters? I just
want to understand whys...

BTW, what's the number (14.8.2.4/17) in your answer? Is that a
chapter, sections of a book I should be looking at to get more
explanation on the issue? Well, I am relatively new to this group so
please bear with me.

Thanks again.
 
V

Victor Bazarov

CoolPint said:
Could you kindly elaborate a little more as to why Types cannot be
deduced
from the default function arguments?

To be honest with you, I suspect that it's due to ambiguity. The
example in the Standard is similar to this:

template<class T> void foo(T t1 = 5, T t2 = 7)
{
}

int main()
{
foo(); // what's 'T'? 'int'? 'char'?
}

I suppose the Standard _allows_ compilers to avoid stretching too
much to try to figure it out because in some cases it's impossible,
so if only part of cases will be covered, the Standard cannot require
it.
Is it because an instantion is
required
at the time of declaration to do so? Is it related to why we cannot
have default arguments for function template type parameters? I just
want to understand whys...

For all "why"s, please ask in comp.std.c++. They talk C++ Standard.
We talk Standard C++. They hold the answers to "why". We try to
answer "how".
BTW, what's the number (14.8.2.4/17) in your answer? Is that a
chapter, sections of a book I should be looking at to get more
explanation on the issue? Well, I am relatively new to this group so
please bear with me.

It's the subsection and the paragraph in the Standard.

Good luck!

Victor
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top