Если вы выполните следующее:
#include <iostream>
int main()
{
std::cout.setf(std::ios::boolalpha);
std::cout << &main << "\n";
std::cout << (void*)&main << "\n"; // The workaround
return 0;
}
// prints something like
// true
// 0x55deee04189a
Если вы удалите вызов std::cout.setf(std::ios::boolalpha)
, он просто напечатает 1
вместо true
.
Если вы посмотрите на https://godbolt.org/z/6CFH3P сборки, вы заметите, что для разрешения шаблона C++
выбирается логический оператор std::basic_ostream<char, std::char_traits<char> >::operator<<(bool)
.
После поиска я нашел решение по вопросу Как печатать указатели на функции cout?
Стандарт C ++ определяет:
4.12 Булевы преобразования
1 Значение арифметического c , перечисление, указатель или указатель на тип члена могут быть преобразованы в значение типа bool.
Это единственное преобразование, указанное для указателей на функции.
Однако он не работает для указателей на функции класса-члена: https://godbolt.org/z/zBN5Va
#include<iostream>
template<class Ret, class... Args>
std::ostream& operator <<(std::ostream& os, Ret(*p)(Args...) ) {
return os << "funptr " << (void*)p;
}
struct test_debugger { void var() {} };
void fun_void_void(){};
void fun_void_double(double d){};
double fun_double_double(double d){return d;}
int main() {
std::cout << "0. " << &test_debugger::var << std::endl;
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:
// 0. 1
// 1. funptr 0x100401080
// 2. funptr 0x100401087
// 3. funptr 0x100401093
Возможно исправить функцию-член iostream cout / cerr указатели печатаются как 1 или правда? Цель состоит в том, чтобы работать с любой свободной функцией или функцией класса-члена без необходимости вручную преобразовывать их в указатель (void *)
перед отправкой их в std::cout
или std::cerr
.
Связанные вопросы:
- Печать указателя с помощью
- Указатель на функцию-член, всегда печатается как «1»
Обновление
Я пытался следовать Дэн М. tip ( generi c указатель на функцию-член в качестве параметра шаблона ):
template <typename T, typename R, typename ...Args>
std::ostream& operator <<(std::ostream& os, R (T::*p)(Args...) ) {
return os << "funptr " << (void*)p;
}
Но выдает это предупреждение: https://godbolt.org/z/yj52hM
$ g++ -o main.exe --std=c++11 test_debugger.cpp && ./main.exe
test_debugger.cpp: In instantiation of ‘std::ostream& operator<<(std::ostream&, R (T::*)(Args ...)) [with T = test_debugger; R = int; Args = {}; std::ostream = std::basic_ostream<char>]’:
test_debugger.cpp:19:42: required from here
test_debugger.cpp:10:31: warning: converting from ‘int (test_debugger::*)()’ to ‘void*’ [-Wpmf-conversions]
return os << "funptr " << (void*)p;
^~~~~~~~
0. funptr 0x100401860
1. funptr 0x100401080
2. funptr 0x100401087
3. funptr 0x100401093
Как правильно исправить предупреждение warning: converting from ‘int (test_debugger::*)()’ to ‘void*’ [-Wpmf-conversions]
?