Вот умный/противный хак с использованием методики, описанной Johannes Schaub - litb на своем блоге, Access to private members: Safer nastiness. Все кредиты должны отправиться в Йоханнес. Я возьму на себя вину за ее применения в реальной ситуации (или, может быть, вы можете):
#include <windows.h>
#include <iostream>
#include "boost/thread.hpp"
using namespace std;
// technique for accessing private class members
//
// from: http://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.html
//
template<typename Tag, typename Tag::type M>
struct Rob {
friend typename Tag::type get(Tag) {
return M;
}
};
struct thread_data_f {
typedef unsigned boost::detail::thread_data_base::*type;
friend type get(thread_data_f);
};
struct thread_id_f {
typedef boost::detail::thread_data_ptr boost::thread::id::*type;
friend type get(thread_id_f);
};
template struct Rob<thread_data_f, &boost::detail::thread_data_base::id>;
template struct Rob<thread_id_f, &boost::thread::id::thread_data>;
unsigned int get_native_thread_id(boost::thread const& t)
{
boost::detail::thread_data_ptr thread_data = t.get_id().*get(thread_id_f());
unsigned thread_id = (*thread_data).*get(thread_data_f());
return thread_id;
}
//
//
//
// test of get_native_thread_id()
void thread_func()
{
cout << "thread running..." << endl;
cout << "Windows says my ID is: " << GetCurrentThreadId() << endl;
for (;;) {
boost::this_thread::yield();
}
}
int main()
{
boost::thread t(thread_func);
::Sleep(2000);
cout << "boost says my thread ID is: " << get_native_thread_id(t) << endl;
return 0;
}
Я не уверен, если это квалифицируется как «хороший путь», чтобы получить информацию. Но он работает без изменения заголовков или библиотек форматирования, и компилятор вообще не жалуется - даже с относительно высокими предупреждениями. Проверено на:
- MinGW 4.6.1
-Wall -Wextra
с несколькими особенно шумными предупреждениями выключено - но не для этого теста, в частности. Они отключены в моем общем сценарии «скомпилировать этот тест».
- VC++ 2008 и 2010 с/W4
Вот пример работы, который показывает, что он работает:
C:\temp>test
thread running...
Windows says my ID is: 5388
boost says my thread ID is: 5388
Конечно, это должно пойти, не говоря, что это может сломаться, если/когда повышение :: нить меняется со временем, но, вероятно, не тихо.
Некоторых пояснительные примечания/указатели:
'лазейка' используется в этой технике в C++ 03 14.7.2/8 "Явной конкретизации":
Обычным доступ правила проверки не применяются к именам, используемым для указания явных экземпляров . [Примечание: в частности, аргументы шаблона и имена, используемые в деклараторе функции (включая типы параметров, типы возвращаемых типов и спецификаций исключений) могут быть частными типами или объектами, которые обычно не доступны, и шаблон может быть членом шаблон или функция-член, которая обычно не была бы доступна .]
Дэйв Абрахамс имеет «суть», который использует подобные методы, наряду с комментариями, которые объясняют довольно хорошо, что происходит:
Я обнаружил, что в комментарии он оставил о предыдущей статье о доступе к частному члену в блоге Johannes: Access to private members. That's easy!
Это самая крутая вещь, которую я видел сегодня. Я буду тратить впустую следующие 3 часа, пытаясь понять это. Благодаря! – PaulH
+1 для дополнительных пояснительных примечаний. – PaulH