Secondo: constexpr static data member giving undefined reference error membri della classe constexpr statici devono soddisfare due requisiti:inizializzazione uniforme del membro constexpr static
template <typename Tp>
struct wrapper {
static constexpr Tp value{}; // 1
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value; // 2
struct foo {
};
int main() {
auto const& x = wrapper<foo>::value;
(void)x;
}
- inizializzato all'interno della definizione della classe (perché è constexpr)
- definita all'esterno della definizione di classe (perché è statica)
Se cambio 1. a initiali uniformi zazione
template <typename Tp>
struct wrapper {
static constexpr auto value = Tp{}; // uniform initialization
};
template<typename Tp>
constexpr Tp wrapper<Tp>::value;
compilatore si lamenta dichiarazioni circa contrastanti:
$ g++ prog.cc -Wall -Wextra -std=c++1z -pedantic
prog.cc:7:31: error: conflicting declaration 'constexpr const Tp wrapper<Tp>::value' constexpr Tp wrapper<Tp>::value;
prog.cc:3:29: note: previous declaration as 'constexpr const auto wrapper<Tp>::value' static constexpr auto value = Tp{};
e anche circa inizializzatore mancante:
prog.cc:7:31: error: declaration of 'constexpr const auto wrapper<Tp>::value' has no initializer
Rimozione conflitto 2. estremità di definizione, come previsto, con errore di linker:
In function `main': prog.cc:(.text+0x8): undefined reference to `wrapper<foo>::value'
Esempio di codice online.
È possibile/legale utilizzare l'inizializzazione uniforme per i membri della classe constexpr statici?
Questo ha qualcosa a che fare con il parametro di template: Funziona come previsto se il tipo del membro dati statico non dipende dal parametro di template, come valore constexpr auto 'statica = int {}; ' – dyp
questa classe wrapper è in realtà una sostituzione del modello di variabile C++ 14 in gcc <5.0, quindi il parametro template è obbligatorio –
Hai bisogno di usare' auto'? –