2017-01-25 2 views
2

型がshared_ptrであるかどうかを調べるテンプレート化された方法を得たいと思います。それに基づいて、関数の新しい特殊化が必要です。コンパイル時に型がshared_ptrであるかどうかを検出する方法

例主な機能はt.valueが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); 
} 

です。 私は、以下の

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シリアルライブラリの一部です。私はカスタマイズしようとしています。

+0

'NameValuePair'は' t.value'が何であるかを伝えるメンバー型を持っていますか? – TartanLlama

+0

ここでNameValuePairが定義されています。 https://uscilab.github.io/cereal/assets/doxygen/helpers_8hpp_source.html .itには型の値メンバーがあります。 –

+0

「直接的な」過負荷が作用するはずです。http://coliru.stacked-crooked.com/a/db3eae53e609bcfc – sp2danny

答えて

6

以下が役立つことがあります。

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

+0

私の場合は動作しますか?実際には、valueというメンバの型に基づいて関数の新しい特殊化を取得する必要があります。 T :: valueがshared_ptrならば、私は新しい専門化が必要です。 –

+0

SFINAEを有効にするための回答が更新されました.value –

4

これは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, ""); 
関連する問題