2012-12-25 12 views
9

Załóżmy, że chcę wymusić ograniczenie, że parametr szablonu przekazany jest potomkiem Foo.Jak wymusić ograniczenie typu dziecko-X w parametrze szablonu?

Czy istnieje sposób na egzekwowanie tego poprzez cechy typu? Niepowodzenie kompilacji static_assert byłoby świetne.

W poniższym kodzie ustawmy to jako dwuczęściowe (oddzielne) pytanie.

  1. Pozwala na kompilację tylko My_Limited_Template<Bar>.
  2. Umożliwiają tylko kompilację My_Limited_Template<TBar>.

EDIT przepraszam za zły nazewnictwa: TBar i TBaz mają być zajęcia non-szablon na celach. Właśnie dołączony T przed nazwami disambiguate z klas w części 1.

KOD

struct Foo { };    // no 
struct Bar : public Foo { }; // yes 
struct Baz { };    // no 

template< typename T > 
struct TFoo { };      // no 
struct TBar : public TFoo<TBar> { }; // yes 
struct TBaz { };      // no 

template< typename T > 
struct My_Limited_Template 
{ 
    // Part One: 
    // My_Limited_Template<Foo> // disallow 
    // My_Limited_Template<Bar> // allow 
    // My_Limited_Template<Baz> // disallow 
    // 
    // Part Two: 
    // My_Limited_Template<TFoo<int>> // disallow 
    // My_Limited_Template<TBar>  // allow 
    // My_Limited_Template<TBaz>  // disallow 
}; 
+1

Tak więc druga część będzie * "tylko pozwolić parametry, które pochodzą od TFoo za pomocą CRTP" *? – jrok

+0

@jrok +1, jeśli mógłbyś włączyć CRTP, byłoby jeszcze lepiej, ale nie jestem pewien, czy to możliwe! – kfmfe04

+0

Chodziło mi o to, że ** ty ** używałeś CRTP podczas wyprowadzania TBar. Czy jest to jedyne dziecko 'TFoo', na które chcesz zezwolić, czy może mieć coś takiego jak: struct X: TFoo {};'? – jrok

Odpowiedz

1

Zakładam, że popełnił błąd w definicji TBar i TBas sprawdzić, czy mój modyfikacji jest poprawne.

#include <type_traits>  

struct Foo { };    // don't allow this 
struct Bar : public Foo { }; // allow this 
struct Baz { };    // don't allow this 

template< typename T > struct TFoo { };      
template< typename T > struct TBar : public TFoo<TBar<T>> { }; 
template< typename T > struct TBaz { };      

template< typename T > 
struct My_Limited_Template 
{ 
     static_assert(
       (std::is_base_of<Foo,T>::value && !std::is_same<T,Foo>::value) 
       || 
       (std::is_base_of<TFoo<T>,T>::value && !std::is_same<T,TFoo<T>>::value), 
       "fail2" 
     ); 
}; 
+1

Nie sądzę, że twoja druga część jest właściwa (dlaczego uważasz, że pytanie jest błędne?). IIUC, pytanie wymaga, aby 'T' było podklasą jakiegoś (nieokreślonego) wystąpienia' TFoo', podczas gdy twoja odpowiedź wymaga, żeby 'T' był podklasą specyficznie' TFoo '. – Mankarse

Powiązane problemy