Search code examples
c++c++20c++-concepts

Concept for smart pointers


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?


Solution

  • 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;