Reputation: 3
I have searched the web, but I could not find the answer to my problem> Why does the C++ template code not compile? Once I remove the last line before the return statement, it compiles and runs as expected.
I use g++ version 4.3.4. I will greatly appreciate the expert help.
Regards, maicah
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <stdint.h>
#include <boost/lexical_cast.hpp>
void mult(int* ptr)
{
std::cout << "void mult(" << *ptr << "): line: " << __LINE__ << ", function: "<< __FUNCTION__ << std::endl;
}
template <typename T>
void multIndirect(T* x)
{
std::cout << "void mult(" << *x << "): line: " << __LINE__ << ", function: "<< __FUNCTION__ << std::endl;
}
void apply(void (*funcPtr)(int*), int* pVal)
{
std::cout << "apply(" << boost::lexical_cast<std::string>((uintptr_t) funcPtr) << ", " << *pVal << "): line:" << __LINE__ << ", function: " << __FUNCTION__ << std::endl;
funcPtr(pVal);
}
template <typename Func, typename T>
void applyIndirect(Func funcPtr, T* x)
{
std::cout << "apply(" << boost::lexical_cast<std::string>((uintptr_t) funcPtr) << ", " << *x << "): line:" << __LINE__ << ", function: " << __FUNCTION__ << std::endl;
funcPtr(x);
}
int main(void) {
int y = 300;
mult(&y);
apply(mult, &y);
apply(multIndirect, &y);
applyIndirect(multIndirect, &y);
return EXIT_SUCCESS;
}
I get the compiler error:
CPPTemplate.cpp: In function int main():
CPPTemplate.cpp:47: error: no matching function for call to applyIndirect(<unresolved overloaded function type>, int*)
make: *** [CPPTemplate.o] Error 1
Upvotes: 0
Views: 120
Reputation: 320371
How do you expect the compiler to deduce the actual value of template parameter Func
for applyIndirect
and, consequently, template parameter T
for multIndirect
from this call
applyIndirect(multIndirect, &y);
?
In this call multIndirect
's T
could be double
or char
or SomeOtherType
or anything else. You made your Func
parameter a completely free type and you provided the compiler with absolutely no means to figure out what type it is supposed to be. This is what causes the error.
Given your declaration of applyIndirect
, to make it compile you have to explicitly tell the compiler the value of T
in multIndirect
applyIndirect(multIndirect<int>, &y);
Now knowing the type of multIndirect<int>
the compiler will be able to figure out what Func
is supposed to be. Or, alternatively, you can explicitly tell the compiler the value of Func
in applyIndirect
applyIndirect<void (int *)>(multIndirect, &y);
Knowing the value of Func
the compiler will be able to figure out what T
for multIndirect
is supposed to be.
However, looking at the body of your applyIndirect
it looks like you want to use funcPtr
with parameter x
of type T *
. That means that type of funcPtr
is not really supposed to be a free type. It is supposed to actually depend on T
. Why did you make it a free type then? Why did you introduce that extra template parameter Func
? What was the purpose of that?
Instead of introducing an extra template parameter, you should have simply declared your applyIndirect
as
template <typename T>
void applyIndirect(void funcPtr(T *), T *x)
{
funcPtr(x);
}
That would be immediately consistent with how apply
is declared.
Now the compiler will understand the link between the type of x
and the required type of funcPtr
. With such declaration you will be able to call
applyIndirect(multIndirect, &y);
The compiler will figure out from the type of &y
that T
is int
. This, in turn, will mean that the type of funcPtr
is void (int *)
. And that will make it instantiate multIndirect
for T == int
.
Upvotes: 1
Reputation: 105876
You have to specify which multIndirect<T>
you want to apply indirect:
applyIndirect(multIndirect<int>, &y);
You don't need to specify the type if you use apply
, because the compiler infers the correct type:
void apply(void (*funcPtr)(int*), int* pVal);
// ^^^^^^^^^^^^^^^^^^^^^
Upvotes: 2