vendettaaaaa
25-06-2013, 23:08
Ciao, ho questo curioso comportamento con il seguente codice nel file BbVector.hpp:
class BbVector
{
[...cut...]
private:
// ****************** Constructor functions
void create();
void create(size_type n, const double& val);
template<class Iter>
void create(Iter b, Iter e);
void uncreate();
[...cut...]
public:
// ****************** Constructors
BbVector() { create(); }
explicit BbVector(size_type n, const double& val = 0.) { create(n, val); }
BbVector(size_type n, const double* arr) { create(arr, arr + n); }
BbVector(const_iterator begin, const_iterator end) { create(begin, end); }
BbVector(const BbVector& other) { create(other.cbegin(), other.cend()); }
BbVector(BbVector&& other)
: myVector{other.myVector}, start{other.start}, avail{other.avail}, limit{other.limit}, mySize{other.mySize}
{ other.myVector = other.start = other.avail = other.limit = nullptr; }
BbVector(const std::initializer_list<double>& list);
explicit BbVector(const std::vector<double>& vec);
BbVector(const ColumnIterator& begin, const ColumnIterator& end);
Ebbene, se nel main scrivo:
BbVector a{ 2., 4. };
BbVector b{ a };
il codice compila tranquillamente usando GCC 4.8.1 in Debug/Release, e usando Clang in Debug. MA, Clang in release mi dà linker error:
"error: undefined reference to `void BbMath::BbVector::create<double const*>(double const*, double const*)'
Cioè: la funzione template<class Iter> create(Iter b, Iter e) è istanziata direttamente nell'header dov'è definita, poichè chiamata nel copy constructor del vector. E a quanto pare non viene vista dal linker. Se sposto il corpo del costruttore nel file BbVector.cpp, tutto va a posto.
Questo che significa? Che opzione di compilazione può causare questo problema? Vi risulta un comportamento anomalo o corretto? Non vorrei spostare il corpo del costruttore fuori dalla dichiarazione della classe, in quanto non sarebbe più inlined...
class BbVector
{
[...cut...]
private:
// ****************** Constructor functions
void create();
void create(size_type n, const double& val);
template<class Iter>
void create(Iter b, Iter e);
void uncreate();
[...cut...]
public:
// ****************** Constructors
BbVector() { create(); }
explicit BbVector(size_type n, const double& val = 0.) { create(n, val); }
BbVector(size_type n, const double* arr) { create(arr, arr + n); }
BbVector(const_iterator begin, const_iterator end) { create(begin, end); }
BbVector(const BbVector& other) { create(other.cbegin(), other.cend()); }
BbVector(BbVector&& other)
: myVector{other.myVector}, start{other.start}, avail{other.avail}, limit{other.limit}, mySize{other.mySize}
{ other.myVector = other.start = other.avail = other.limit = nullptr; }
BbVector(const std::initializer_list<double>& list);
explicit BbVector(const std::vector<double>& vec);
BbVector(const ColumnIterator& begin, const ColumnIterator& end);
Ebbene, se nel main scrivo:
BbVector a{ 2., 4. };
BbVector b{ a };
il codice compila tranquillamente usando GCC 4.8.1 in Debug/Release, e usando Clang in Debug. MA, Clang in release mi dà linker error:
"error: undefined reference to `void BbMath::BbVector::create<double const*>(double const*, double const*)'
Cioè: la funzione template<class Iter> create(Iter b, Iter e) è istanziata direttamente nell'header dov'è definita, poichè chiamata nel copy constructor del vector. E a quanto pare non viene vista dal linker. Se sposto il corpo del costruttore nel file BbVector.cpp, tutto va a posto.
Questo che significa? Che opzione di compilazione può causare questo problema? Vi risulta un comportamento anomalo o corretto? Non vorrei spostare il corpo del costruttore fuori dalla dichiarazione della classe, in quanto non sarebbe più inlined...