Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect if a type is shared_ptr at compile time

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.

like image 477
Mr.100 Avatar asked Jan 25 '17 13:01

Mr.100


People also ask

How slow is shared_ptr?

Admittedly, the std::shared_ptr is about two times slower than new and delete. Even std::make_shared has a performance overhead of about 10%.

What is the difference between Make_shared and shared_ptr?

The difference is that std::make_shared performs one heap-allocation, whereas calling the std::shared_ptr constructor performs two.

Where is shared_ptr defined?

Defined in header <memory> template< class T > class shared_ptr; (since C++11) std::shared_ptr is a smart pointer that retains shared ownership of an object through a pointer.

Should I use Unique_ptr or shared_ptr?

Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another. A shared_ptr is a container for raw pointers.


1 Answers

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

like image 84
Biggy Smith Avatar answered Oct 11 '22 09:10

Biggy Smith