【问题标题】:How to detect if a type is shared_ptr at compile time如何在编译时检测类型是否为 shared_ptr
【发布时间】:2017-06-10 17:25:19
【问题描述】:

我想获得一种模板化的方式来查找一个类型是否是 shared_ptr 并且基于此我想要一个函数的新专业化。

示例主要功能是,

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 );
}

如果 t.value 是 shared_ptr 那么我想要一个不同的函数专业化。 下面我试过了,

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 );
  }

但它似乎不起作用。这些是 c++11 谷物库的一部分。我正在尝试自定义。

【问题讨论】:

标签: c++ c++11 templates shared-ptr cereal


【解决方案1】:

以下可能会有所帮助:

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

【讨论】:

  • 它在我的情况下是否有效。实际上,我必须根据名为 value 的成员的类型对函数进行新的专门化。如果 T::value 是 shared_ptr 那么我需要新的专业化。
  • 这看起来像是问题的正确答案。
【解决方案2】:

这是template specialization 的基本情况。以下是确定类型 T 是否为 shared_ptr 的类型特征。可以和你已经用过的std::is_pointer一样使用。

#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 {};

演示:

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

【讨论】:

  • 我喜欢这个答案的简单性。
【解决方案3】:

如果提供的类型本身是某个未知类型 T 的 std::shared_ptr,那么以下使用 SFINAE 应该会有所帮助!由于所有智能指针都提供成员类型“element_type”,因此我们可以专门针对std::shared_ptr&lt;T&gt;std::weak_ptr&lt;T&gt;std::unique_ptr&lt;T&gt;,如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 1970-01-01
    • 2019-05-25
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多