Given a class template like this:
template<typename T>
struct foo
{
T data;
};
How may one determine whether T
is a smart pointer such as std::shared_ptr<T_underlying>
using C++20 concepts?
I want to add functionality to foo<T>
based on this criteria. For example, Instead of using SFINAE, I'd like to use the new concept system.
I want to achieve something like this:
template<typename T>
struct foo
{
T data;
void func()
requires is_shared_ptr_v<T>
{
// ...
}
};
Are there existing concepts for this in the STL? If not, I assume I can write a concept for std::shared_ptr
, one for std::unique_ptr
and so on and then tie them together with logical or in a general is_smart_pointer
concept?
You might first create a traits to detect if type is a std::shared_ptr
(way depends if you want to consider inheritance or not).
And then use the traits to build a concept:
template <typename T> struct is_shared_ptr : std::false_type {};
template <typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
template <typename T> concept IsSharedPtr = is_shared_ptr<T>::value;
or
template <typename T>
std::true_type inherit_from_shared_ptr_impl(const std::shared_ptr<T>*);
std::false_type inherit_from_shared_ptr_impl(...);
template <typename T>
using inherit_from_shared_ptr =
decltype(inherit_from_shared_ptr_impl(std::declval<T*>()));
template <typename T> concept InheritFromSharedPtr = inherit_from_shared_ptr<T>::value;