Re: deducing the argument type of overloaded function call operator
On 16 juil, 16:21, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote:
In the following program I have used 'for_each' algorithm for learning
purpose only. (I will use ' copy' algorithm along with
ostream_iterator in real code).
Consider the program x.cpp:
[snip]
using namespace std;
class Print
{
public:
explicit Print(ostream& arg);
Using explicit here is a non-sense.
Print(const Print& rhs);
template <typename T> void operator()(const T& arg);
private:
ostream* os;
};
[snip]
template <typename T>
inline void Print::operator()(const T& arg)
{
*os << arg << endl;
return;
}
int main()
{
cout << "Enter a set of integers" << endl;
typedef vector<int> Container;
istream_iterator<Container::value_type> isi(cin);
istream_iterator<Container::value_type> eos;
Container c(isi, eos);
ofstream ofs("output.txt");
if (!ofs)
{
cout << "Could not create output file" <<=
endl;
return EXIT_FAILURE;
}
for_each(c.rbegin(), c.rend(), Print(ofs));
return EXIT_SUCCESS;
}
In the above program, consider the line:
for_each(c.rbegin(), c.rend(), Print(ofs));
Here I am passing a temporary function object of type 'Print' as the
third argument to the 'for_each' algorithm. The 'for_each' algorithm
will apply this function object to every iterator in the range
[c.rbegin(), c.rend()). But the overloaded function call operator will
be called with '*ri', for an iterator 'ri' in this range, only at run-
time - ie the type of the argument to the overloaded function call
operator will be known at run-time only. Am I correct ?
No. The type of the argument is known are compile time.
'*ri' is of type std::vector<int>::iterator::reference.
If this is so,
I do not understand how the compiler is able to deduce at compile-time
the type 'T' of the function template namely the overloaded function
call operator given by
template <typename T> void operator()(const T& arg);
Kindly explain, if necessary with example code.
The compiler will set up a list of candidate function (i.e. function
that match the name) and consider them in order (see 13.3 of the
standard).
Eventually the compiler will have a best match by instantiating a
specialisation Print::operator()(const int& arg).
In the above program, suppose I make the class 'Print' a class
template thereby making the overloaded function call operator an
ordinary member function instead of a member function template.That is
I have:
template <typename T> class Print
[snip]
Then the call to 'for_each' algorithm becomes:
for_each(c.rbegin(),
c.rend(),
Print<Container::value_type>(=
ofs));
My question: Which of the two 'for_each' algorithm calls
for_each(c.rbegin(), c.rend(), Print(ofs));
and
for_each(c.rbegin(),
c.rend(),
Print<Container::value_type>(=
ofs));
is efficient ?
Both are equivalent.
Kindly explain.Here I am just printing. In real code
the overloaded function call operator may perform some task. Given
this, which of the two approaches should be preferred ? Kindly
explain.
This is a design issue.
There may be some advantage to using the second form because it let
you more freedom regarding partial specialisation (exemple: with the
1st form, you cannot partially specialize on template of pointer
parameters) but this comes at the cost of redefining the other member
functions of the class.
--
Michael