I was trying if I could replace my code for 2-, 3- and 4--dimensional vectors into 1 class, so instead of having vec2<T>
, vec3<T>
and vec4<T>
, use vecN<typenameT,unsignedS>
.
That seems to work well but the overloaded cout
function for printing the vectors gives an undefined reference
error. I cannot see what I'm doing differently than the usual:
(minimised) class vectors.hpp
:
#include<vector>
#include<iostream>
#include<ranges>
template <typename T, unsigned S>
class vecN {
template <typename U> friend std::ostream& operator<< ( std::ostream& out, const vecN<U,S>& v);
template <typename U> friend std::istream& operator>> ( std::istream& in, vecN<U,S>& v);
protected:
std::vector<T>
data;
public:
vecN ( T* xyz ): data ( S ) { std::copy (xyz, xyz+S, data.begin() ); }
};
// non-members of vecN for vecN
template <typename T, unsigned S>
std::ostream& operator<<(std::ostream& out, const vecN<T,S>& v) {
out << "( ";
std::copy(v, std::ostream_iterator<char>(out, ", "));
out << "\b\b )"; // use two ANSI backspace characters '\b' to overwrite final ", "
return out;
}
template <typename T, unsigned S>
std::istream& operator>>(std::istream& in , vecN<T,S> &v) {
for ( auto i : std::views::iota(0u, S) )
in >> v.data[i];
return in;
}
// aliases for 2-, 3- and 4-dimensional vectors
template <typename T>
using vec2 = vecN<T,2>;
template <typename T>
using vec3 = vecN<T,3>;
template <typename T>
using vec4 = vecN<T,4>;
Test file main.cpp
:
#include "vectors.hpp"
int main() {
float v[2] = { 10, 20 };
vec2<float> v2_1 ( v );
std::cout << "vector v2_1 \n" << v2_1 << "\n";
return 0;
}
When I compile them with:
g++ -std=c++20 -o test main.cpp vectors.hpp
then I get the error
in function `main':
main.cpp:(.text+0x6a): undefined reference to `std::ostream& operator<< <float>(std::ostream&, vecN<float, 2u> const&)'
collect2: error: ld returned 1 exit status
But the compiled code for this vector type (float values, size 2) should end up in the test
binary, shouldn't it? The types and values are determined correctly, but it does not seem to include the code?