After the question Is possible to fix the iostream cout/cerr member function pointers being printed as 1 or true? I am trying to write a C++ 98 compatible way to print any function pointer.
For this, I am using a fake C++ "variadic" template, i.e., writing all function definitions up to n parameters. However my fake variadic only works for function pointer with 0 arguments as show on the next example: https://godbolt.org/z/x4TVHS
#include<iostream>
template<typename Return>
std::ostream& operator <<(std::ostream& os, Return(*pointer)() ) {
return os << (void*) pointer;
}
template<typename Return, typename T0>
std::ostream& operator <<(std::ostream& os, Return(*pointer)( const T0& t0 ) ) {
return os << (void*) pointer;
}
template<typename Return, typename T0, typename T1>
std::ostream& operator <<(std::ostream& os, Return(*pointer)( const T0& t0, const T1& t1 ) ) {
return os << (void*) pointer;
}
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main() {
std::cout << "1. " << fun_void_void << std::endl;
std::cout << "2. " << fun_void_double << std::endl;
std::cout << "3. " << fun_double_double << std::endl;
}
// Prints:
// 1. funptr 0x100401080
// 2. funptr 1
// 3. funptr 1
If I write the equivalent version using C++11 real variadic templates, then everything works fine: https://godbolt.org/z/s6wdgp
#include<iostream>
template<typename Return, typename... Args>
std::ostream& operator <<(std::ostream& os, Return(*pointer)( Args... ) ) {
return os << (void*) pointer;
}
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main() {
std::cout << "1. " << fun_void_void << std::endl;
std::cout << "2. " << fun_void_double << std::endl;
std::cout << "3. " << fun_double_double << std::endl;
}
// Prints:
// 1. funptr 0x100401080
// 2. funptr 0x100401087
// 3. funptr 0x100401093
After analyzing the code, I noticed the only difference between then is that the types on the C++11 example are not const references. Then, I removed the constness and reference from the C++98 ones and it started working: https://godbolt.org/z/ZrF66b
#include<iostream>
template<typename Return>
std::ostream& operator <<(std::ostream& os, Return(*pointer)() ) {
return os << (void*) pointer;
}
template<typename Return, typename T0>
std::ostream& operator <<(std::ostream& os, Return(*pointer)( T0 ) ) {
return os << (void*) pointer;
}
template<typename Return, typename T0, typename T1>
std::ostream& operator <<(std::ostream& os, Return(*pointer)( T0, T1 ) ) {
return os << (void*) pointer;
}
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main() {
std::cout << "1. " << fun_void_void << std::endl;
std::cout << "2. " << fun_void_double << std::endl;
std::cout << "3. " << fun_double_double << std::endl;
}
// Prints:
// 1. funptr 0x100401080
// 2. funptr 0x100401087
// 3. funptr 0x100401093
Why the function pointer templates definitions are not matching when they are const and/or references?
Aucun commentaire:
Enregistrer un commentaire