How to detect if a type is shared_ptr at compile time

杀马特。学长 韩版系。学妹 提交于 2020-08-02 04:04:45

问题


I want to get a templatized way of finding if a type is a shared_ptr and based on that I want to have a new specialization of a function.

Example main function is,

template <class T> inline
void CEREAL_LOAD_FUNCTION_NAME( RelaxedJSONInputArchive & ar,    NameValuePair<T> & t )
{
    std::cout << " CEREAL_LOAD_FUNCTION_NAME NameValuePair 1 " << std::endl;
     ar.setNextName( t.name );
     ar( t.value );
}

If t.value is shared_ptr then I want to have a different function specialization. I have tried below,

template <class T> inline
typename std::enable_if<is_pointer<T>::value, void>::type
CEREAL_LOAD_FUNCTION_NAME( RelaxedJSONInputArchive & ar, NameValuePair<T> & t )
 {
    std::cout << " CEREAL_LOAD_FUNCTION_NAME NameValuePair 2 " << std::endl;
   ar.setNextName( t.name );
   ar( t.value );
  }

But it does not seem to work. These are part of c++11 cereal library. Which I am trying to customize.


回答1:


the following may help:

template<typename T> struct is_shared_ptr : std::false_type {};
template<typename T> struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};

then you can do the following to get the correct function:

template <class T> 
typename std::enable_if<is_shared_ptr<decltype(std::declval<T>().value)>::value, void>::type
func( T t )
{
    std::cout << "shared ptr" << std::endl;
}

template <class T> 
typename std::enable_if<!is_shared_ptr<decltype(std::declval<T>().value)>::value, void>::type
func( T t )
{
    std::cout << "non shared" << std::endl;
}

live demo




回答2:


This is a basic case of template specialization. The following is a type trait that determines if a type T is a shared_ptr or not. It can be used the same way std::is_pointer, which you already use.

#include <memory>
#include <type_traits>

template<class T>
struct is_shared_ptr : std::false_type {};

template<class T>
struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};

Demonstration :

static_assert(is_shared_ptr<std::shared_ptr<int>>::value == true, "");
static_assert(is_shared_ptr<int>::value == false, "");



回答3:


If the type provided is itself a std::shared_ptr of some unknown type T, then the following use of SFINAE should help! Since all smart pointers provide a member type "element_type" we can specialize for std::shared_ptr<T>, std::weak_ptr<T>, and std::unique_ptr<T> as follows:

template<typename T, typename Enable = void>
struct is_smart_pointer
{
    enum { value = false };
};

template<typename T>
struct is_smart_pointer<T, typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, std::shared_ptr<typename T::element_type>>::value>::type>
{
    enum { value = true };
};

template<typename T>
struct is_smart_pointer<T, typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, std::unique_ptr<typename T::element_type>>::value>::type>
{
    enum { value = true };
};

template<typename T>
struct is_smart_pointer<T, typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, std::weak_ptr<typename T::element_type>>::value>::type>
{
    enum { value = true };
};


来源:https://stackoverflow.com/questions/41853159/how-to-detect-if-a-type-is-shared-ptr-at-compile-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!