I am testing the following code with c++ templates. I have written a square function using int and float and with a function template.
#include <iostream>
using namespace std;
int square (int a){
cout << "int function" << endl;
return a*a;
};
float square (float a){
cout << "float function" << endl;
return a*a;
};
template <typename T>
T square (T x){
cout << "template function" << endl;
return x*x;
}
int main(){
cout << square<int>(5) << endl;
cout << square<float>(5.5) << endl;
cout << square(5) << endl;
cout << square(5.5) << endl;
return 0;
}
The output is
template function
25
template function
30.25
int function
25
template function
30.25
though I expected
template function
25
template function
30.25
template function
25
template function
30.25
Can someone explain the difference ?
It doesn't override anything, it's a better match. That is because 5.5 is a constant of type double, and not of type float.
You don't have any overload for doubles so the template gets instantiated. That's because the template doesn't require a conversion sequence from a double to a float, as opposed to your overload.
If you use a float constant, like so:
cout << square(5.5f) << endl;
It will print
float function
Template does not "override" regular function. Quite the opposite, regular functions usually "win" the overload resolution process, if they match argument types specified in the call. So, it is actually the other way around: all other things being equal, regular function "overrides" template function.
In your case the first two calls go to templates because you explicitly requested templates by using <> in the call. You explicitly prohibited the compiler to use regular functions.
The third call goes to the regular function, since it is an exact match and therefore it "wins", as I stated above.
The fourth call goes to the template version since the existing regular function is not an exact match (float parameter vs. double argument), while the template can be used to generate an exact match.
Related
So I've found a variety of articles and posts saying that there is no way to convert typename to string but I haven't found one about the opposite. I have a template of a function with specializations:
template <typename T>
void foo(T sth) {}
template <>
void foo<int>(int sth) {}
...
and I'm reading from a file constructed like this:
int 20
double 12.492
string word
Is there a way to call the correct specialization of foo() depending on the content of the file?
Yes there is, but it requires manual code and that you know all the types that are going to appear in the file. That's because templates are compile time constructs and they cannot be instantiated at runtime.
You can always use the preprocessor or other tricks to try and reduce the boilerplate if you want to.
void callFoo(std::string type, std::any arg) {
if (type == "int")
foo<int>(std::any_cast<int>(arg));
else if (type == "double")
foo<double>(std::any_cast<double>(arg));
else if (type == "string")
foo<std::string>(std::any_cast<std::string>(arg));
}
Of course, this requires that you pass in the correct type (no implicit conversions!). I don't see any way to avoid that.
To be honest, I am not sure about understanding your question. As I interpret it, I believe that you do not need a kind of dispatcher in running time neither to compute a string containing the type name. Simply you write a general template function that calls a special template wrapper that disambiguates the call to foo() according to the type. You require that the specialized foo() receives a second special parameter (the_type<T>) which is used for disambiguating.
Here a full and operating demo:
# include <string>
# include <iostream>
using namespace std;
template<class T> struct the_type { using type = T; };
template <typename T>
void foo(const T par)
{
foo(par, the_type<T>());
}
void foo(int par, the_type<int>)
{
cout << "int " << par << endl;
}
void foo(double par, the_type<double>)
{
cout << "double " << par << endl;
}
void foo(const string & par, the_type<string>)
{
cout << "string " << par << endl;
}
void foo(const char * par, the_type<const char*>)
{
cout << "char* " << par << endl;
}
int main()
{
foo(20);
foo(12.492);
foo("word");
foo(string("word"));
}
whose output is:
int 20
double 12.492
char* word
string word
If you need another specialization, then you simply define it. In some cases, you will have to explicitly to define the specialization as the template parameter.
You could use macro manips for avoiding repetitive things. For example, given that foo() structure is the same, you could encapsulate it in a macro. Something like this:
# define GENFOO(type_name) \
void foo(type_name par, the_type<type_name>) \
{ \
cout << #type_name " " << par << endl; \
}
GENFOO(int);
GENFOO(double);
GENFOO(string)
However, I would say that each specialized version of foo() would not be so similar.
So I've found a variety of articles and posts saying that there is no way to convert typename to string but I haven't found one about the opposite. I have a template of a function with specializations:
template <typename T>
void foo(T sth) {}
template <>
void foo<int>(int sth) {}
...
and I'm reading from a file constructed like this:
int 20
double 12.492
string word
Is there a way to call the correct specialization of foo() depending on the content of the file?
Yes there is, but it requires manual code and that you know all the types that are going to appear in the file. That's because templates are compile time constructs and they cannot be instantiated at runtime.
You can always use the preprocessor or other tricks to try and reduce the boilerplate if you want to.
void callFoo(std::string type, std::any arg) {
if (type == "int")
foo<int>(std::any_cast<int>(arg));
else if (type == "double")
foo<double>(std::any_cast<double>(arg));
else if (type == "string")
foo<std::string>(std::any_cast<std::string>(arg));
}
Of course, this requires that you pass in the correct type (no implicit conversions!). I don't see any way to avoid that.
To be honest, I am not sure about understanding your question. As I interpret it, I believe that you do not need a kind of dispatcher in running time neither to compute a string containing the type name. Simply you write a general template function that calls a special template wrapper that disambiguates the call to foo() according to the type. You require that the specialized foo() receives a second special parameter (the_type<T>) which is used for disambiguating.
Here a full and operating demo:
# include <string>
# include <iostream>
using namespace std;
template<class T> struct the_type { using type = T; };
template <typename T>
void foo(const T par)
{
foo(par, the_type<T>());
}
void foo(int par, the_type<int>)
{
cout << "int " << par << endl;
}
void foo(double par, the_type<double>)
{
cout << "double " << par << endl;
}
void foo(const string & par, the_type<string>)
{
cout << "string " << par << endl;
}
void foo(const char * par, the_type<const char*>)
{
cout << "char* " << par << endl;
}
int main()
{
foo(20);
foo(12.492);
foo("word");
foo(string("word"));
}
whose output is:
int 20
double 12.492
char* word
string word
If you need another specialization, then you simply define it. In some cases, you will have to explicitly to define the specialization as the template parameter.
You could use macro manips for avoiding repetitive things. For example, given that foo() structure is the same, you could encapsulate it in a macro. Something like this:
# define GENFOO(type_name) \
void foo(type_name par, the_type<type_name>) \
{ \
cout << #type_name " " << par << endl; \
}
GENFOO(int);
GENFOO(double);
GENFOO(string)
However, I would say that each specialized version of foo() would not be so similar.
Xcode 7.2.1 compiler.
Why will this not compile? I would expect that the second line would infer the type, but I'm getting the error posted. Thx.
int square(int);
template <typename T>
T square(T x) { return x * x; }
int main() {
cout << square<int>(2) << endl; //Compiles, works
cout << square(2) << endl; // Error below!?
cout << endl;
return 0;
}
You are declaring a function as well as a template function.
int square(int);
This says that there is some function, square, that exists elsewhere.
template <typename T>
T square(T x) { return x * x; }
Says there is a template called square for arbitrary types. When you call it directly via square<int>(2) you are explicitly referencing the template. When you try to infer it by square(2) the first, declared but undefined function int square(int) is selected, and you get an undefined reference error.
I believe you just want a templated function, so you should delete the int square(int) altogether.
Did you forget to link in object file with definition of fuction(it is preferred by compiler over function template as exact match):
int square(int);
as this one selected on line:
cout << square(2) << endl; // Error below!?
I want to make function which has function pointer as a parameter.
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(double (*fptr)(double), double input){
return fptr(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(t.tt, 3) << endl; // This line doesn't work
cout << fptr_test(&test::tt, 3) << endl; // This line can't compile
return 1;
}
But it doesn't work.
How could I pass class member function as a parameter?
Can I call the member function without instantiation?
If you want to pass a pointer to a member-function, you need to use a member-function-pointer, not a pointer for generic free functions and an object to invoke it on.
Neither is optional.
double fptr_test(test& t, double (test::*fptr)(double), double input){
return t.*fptr(input);
}
// call like this:
fptr_test(&test::tt, 3); // Your second try
A function pointer and a member function pointer have incompatible types. For example, the type of &test::tt is
double (test::*)(double)
rather than
double (*)(double)
The reason for this difference is that a [non-static] member function has a hidden parameter: the pointer to the object the member function is applied, too, i.e., this. The way to a normal function pointer out of a member function is to delegate via a function which supplies the this pointer and, thus, takes an extra argument.
In C++ it is much more useful to not take function pointers as arguments to functions which can be customized by a function but rather to take a function object. This approach comes in two flavors:
The fast approach is to make the function object type a template argument and to just pass whatever function object you got directly. For example, you fptr_test() would look like this:
template <typename Fun>
double fptr_test(Fun fun, double input) {
return fun(input);
}
The implicit concept used is a function callable with a double argument which yields are result convertible to double.
Especially when the functions being called need to be compiled separately, using a template for each kind of function object isn't viable. In that case it is much more reasonable to use a type-erased representation, i.e., std::function<...>, e.g.:
double fptr_test(std::function<double(double)> fun, double input) {
return fun(input);
}
In both cases the function object takes just one argument while your member function takes two: the object to call the function on and the double argument. You'd std::bind(...) the first argument to an object and pass the resulting object to fptr_test():
test object;
std::cout << fptr_test(std:bind(&test::tt, &object, std::placeholders::_1), 3) << '\n';
std::cout << fptr_test([&](double input){ return object.tt(input); }, 3) << '\n';
The code uses two separate approaches to bind the object: the first uses std::bind() while the second uses a lambda function. Both of these calls should work with both of the implementation of fptr_test() provided.
What you probably want is this:
#include <iostream>
#include <functional>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test( std::function<double(double)> func, double input){
return func(input);
}
int main(){
using namespace std::placeholders;
test t;
cout << t.tt(3) << endl;
cout << fptr_test( std::bind( &test::tt, t, _1 ), 3) << endl;
return 0;
}
Btw - when your program finishes correctly you suppose to return 0 from main()
Here is a code after modification.
#include <iostream>
using namespace std;
class test{
public:
test(){};
double tt(double input){
return input;
};
};
double fptr_test(test* t, double (test::*fptr)(double), double input){
return (t->*fptr)(input);
}
int main(){
test t;
cout << t.tt(3) << endl;
cout << fptr_test(&t, &test::tt, 3) << endl;
return 1;
}
Currently, I encounter some difficulty in overloading a certain function. here's my code:
template<typename Value>
bool process(Value thisValue)
{
return processAccordingToTheType(thisValue);
}
So, there are two overloaded function of processAccordingToTheType:
bool processAccordingToTheType(int thisValue){}
bool processAccordingToTheType(string thisValue){}
when I try to compile it, it said:
error C2665: 'processAccordingToTheType' : none of the 2 overloads could convert all the argument types
what do I need to do?
Update:
int main()
{
int i = 1;
process <int> (i);
}
From your sample code I understand you need two things to be done:
Call a type specific process function
Restrict these calls to string and int types
Wrapping the processAccordingToType function inside process<T> is completely redundant: process<T> actually means 'process according to type'. The keyword here is 'template specialization'. You need to specialize your 'process according to type' method for int and string.
You can do this as below:
#include <iostream>
using namespace std;
template<typename T>
bool process(T t)
{
// call a Compile-Time Assertion
cout << "I don't want this to be called." << endl;
}
template <>
bool process<int>(int i)
{
cout << "process(int) called." << endl;
}
template <>
bool process<string>(string s)
{
cout << "process(string) called." << endl;
}
int main()
{
process(1);
process(string("s"));
process(1.0d);
}
Output:
process(int) called.
process(string) called.
I don't want this to be called.
Ideally, you want to prevent the users of your API calling process with other types. Allowing them to call and handling this at runtime (like it's done in my example) is not acceptable. You achieve this with Compile-Time Assertions. Read "Modern C++ Designs" by Andrei Alexandrescu for ways of doing that.
Look into template specialization. Does what you're looking for without deferring to another function based on type.
http://www.cprogramming.com/tutorial/template_specialization.html
You can overload function templates with either a non-template function or another template function. Make sure that whatever you do, you test incrementally as template errors are notoriously hard to understand.
http://www.cplusplus.com/doc/tutorial/templates/
#include <iostream>
using namespace std;
template <typename Value>
bool processAccordingToTheType( Value thisValue ){
cout << "Generic Type" << endl;
return false;
}
bool processAccordingToTheType(int thisValue){
cout << "int type" << endl;
return true;
}
template <typename Value>
bool process( Value thisValue ){
return processAccordingToTheType(thisValue);
}
int main( int argc, char* argv[] ){
cout << process( 1 ) << endl;
cout << process( "Hello" ) << endl;
return 0;
}