2016-06-22 10 views
5

Come posso affermare staticamente che un'espressione è un std::unique_ptr, ad esempio std::unique_ptr<T> per qualsiasi T.static_assert per unique_ptr di qualsiasi tipo

static_assert (std::is_pointer<decltype(exp)>()), "not a smart pointer") 

Sopra non funziona. Se nulla di diretto, sono interessato solo se l'operatore bool() è definito per il tipo.

+0

Si noti che le risposte migliori (al momento) si basano su 'std :: true_type' e così via. Quelli sono parte del prossimo C++ 17 e potresti dover riscrivere la soluzione usando lo 'std :: integral_constant' attualmente disponibile – StoryTeller

+2

@StoryTeller Huh? 'std :: true_type' è disponibile da C++ 11. Potresti averlo confuso con il modello alias 'std :: bool_constant'. – cpplearner

+0

@cpplearner, sembra che tu abbia ragione. Mi sono bloccato nella mia mente che i tre vanno di pari passo. Oh bene. – StoryTeller

risposta

6

Crea il tuo carattere, con la specializzazione parziale appropriata:

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

template <class T, class D> 
struct is_unique_ptr<std::unique_ptr<T, D>> : std::true_type 
{}; 
+0

L'esempio sopra non sembra funzionare per i puntatori unici di 'const'. Ad esempio, 'is_unique_ptr > :: value' è falso. – camelCase

3

È possibile creare un tratto per questo:

template <typename T, typename D> 
std::true_type is_unique_ptr_impl(const std::unique_ptr<T, D>&, int); 

template <typename T> 
std::false_type is_unique_ptr_impl(const T&, ...); 

template <typename T> 
using is_unique_ptr = decltype(is_unique_ptr_impl(std::declval<T>(), 0)); 
1

È possibile utilizzare questo:

static_assert(std::is_same<decltype(expr), 
    std::unique_ptr<std::remove_pointer<decltype(expr.get())>::type>>::value, ""); 

Fondamentalmente , ciò che fa è creare un std::unique_ptr fuori dal tipo da std::unique_ptr::get(), e confrontandolo con expr. Questo sarà sempre vero solo se expr è un std::unique_ptr.

+0

cosa succede se 'exp' non implementa' .get'? – dashesy

+0

@dashy Allora fallirebbe ancora :) – Rakete1111

+0

Quindi funziona in un modo :) solo non con il messaggio di asserzione dato – dashesy