cppreference indicates std::thread::id
only has 1 constructor. libstdc++ contains the following additional public constructor:
explicit id(native_handle_type __id) : _M_thread(__id) { }
Is 'cppreference' out-of-date, or is this constructor not part of the standard? If it's not part of the standard, why would it be public given that std::thread
is a friend of std::thread::id
?
Standard library implementations are allowed to add any functions, public or otherwise, to any class, so long as they do not interfere with the standard-defined interfaces. Specifically, if some expression would, through overload resolution, call a particular function defined in the standard library, then it must actually call a function causing that behavior. std::thread::id(some_native_handle)
would not call the standard-defined id
constructor. So it is permissible for the library implementation to have it call something else.
That is, code that should work a certain way by the standard will work that way. Code that wouldn't work might be otherwise permitted to do something, but this is ultimately unspecified and cannot be relied upon across implementations.
No, cppreference is not out of date. The constructor is an extension.
Here's the public interface described in the C++23 draft
33.4.3.2 Class thread::id
[thread.thread.id]
namespace std {
class thread::id {
public:
id() noexcept;
};
bool operator==(thread::id x, thread::id y) noexcept;
strong_ordering operator<=>(thread::id x, thread::id y) noexcept;
template<class charT, class traits>
basic_ostream<charT, traits>&
operator<<(basic_ostream<charT, traits>& out, thread::id id);
// hash support
template<class T> struct hash;
template<> struct hash<thread::id>;
}
why would it be public given that
std::thread
is a friend ofstd::thread::id
?
It's also used by the free function this_thread::get_id()
and making it public also lets other users of the class use the implementation specific constructor.
namespace this_thread
{
/// this_thread::get_id
inline thread::id
get_id() noexcept
{
#ifndef _GLIBCXX_HAS_GTHREADS
return thread::id(1);
#elif defined _GLIBCXX_NATIVE_THREAD_ID
return thread::id(_GLIBCXX_NATIVE_THREAD_ID);
#else
return thread::id(__gthread_self());
#endif
}
}
The LLVM version does not have a similar thread::id
constructor. It's simply defined with the constructor required by the standard:
namespace std {
class thread::id
{
public:
id() noexcept;
};
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With