2015-11-05 18 views
6

Sto provando a scrivere un CRTP per contenere un static constexpr del tipo derivato, poiché è impossibile farlo con una sola classe. Questo codice si compila bene in GCC, ma clang si lamenta che Derived è un tipo incompleto. Quale è giusto?Una definizione di classe è completa quando viene passata a una classe base?

template<class T> 
class Base { 
public: 
    static constexpr T a = T(1), b = T(20); 
}; 

class Derived : public Base<Derived> { 
public: 
    int x; 
    constexpr Derived(int x) : x(x) {} 
}; 
+1

Fare attenzione al costruttore di Derived la variabile locale x e il membro hanno lo stesso nome – Brahim

+0

Voglio solo sottolineare che mantenere gli oggetti derivati ​​come statici all'interno della classe base non è l'idea migliore .. –

+0

L'unico motivo per farlo in questo modo non posso mettere un 'constexpr' statico del tipo' Derivato' in 'Derivato'. Volevo essere in grado di farlo: 'Derived :: a' invece di qualcosa come' Derived :: constants :: a'. – user975989

risposta

2

Derived è incompleto nel punto in cui viene istanziata Base<Derived> ([class.mem]/2), che avviene giusto al momento definizione. Hai usato constexpr, che richiede un inizializzatore come per [class.static.data]/3, e quando viene creato il Base<Derived>, così come le dichiarazioni dei suoi membri di dati statici ([temp.inst]/3), che include gli inizializzatori. Tuttavia, gli inizializzatori stanno tentando di creare un oggetto di tipo incompleto, che è mal formato.

è possibile dichiarare il vostro membro come const invece:

template<class T> 
class Base { 
public: 
    static const T a; 
}; 
template <typename T> 
constexpr T Base<T>::a = T(1); 

poiché l'inizializzatore è ora alla definizione, la creazione di istanze di questa inizializzazione può essere differito fino esempio Derived è completo. Demo con Clang.

Si noti che Clang non tratta ancora a come constexpr perché non riesce ad istanziare con entusiasmo la sua definizione. Vedi bug #24541.

+0

Ma poi non si può fare 'static_assert (Derived :: ax == 1," ")', che tipo di sconfigge lo scopo di 'constexpr'. – user975989

+0

@ user975989 Sembra un bug Clang. – Columbo

+0

@ user975989 Trovato il DR e aggiunto alla risposta. (Stranamente, l'esempio usato è molto sul punto!) – Columbo

Problemi correlati