Linker não encontra referências
Boa noite.
Estou tendo problemas para compilar um código, não tenho ideia do que está acontecendo.
Spoiler
[main] Compilando a pasta: Math
[build] Iniciando o build
[proc] Executando o comando: /usr/bin/cmake --build /home/mateusgp/vscProjects/Math/build --config Debug --target all -- -j 6
[build] Scanning dependencies of target vector
[build] [ 66%] Building CXX object CMakeFiles/vector.dir/main.cpp.o
[build] [ 66%] Building CXX object CMakeFiles/vector.dir/vector2.cpp.o
[build] [100%] Linking CXX executable vector
[build] /usr/bin/ld: CMakeFiles/vector.dir/main.cpp.o: na função "main":
[build] /home/mateusgp/vscProjects/Math/main.cpp:9: referência não definida para "Vector2<float>::dot(Vector2<float> const&) const"
[build] collect2: error: ld returned 1 exit status
[build] gmake[2]: *** [CMakeFiles/vector.dir/build.make:118: vector] Erro 1
[build] gmake[1]: *** [CMakeFiles/Makefile2:339: CMakeFiles/vector.dir/all] Erro 2
[build] gmake: *** [Makefile:136: all] Erro 2
[build] Build concluído com o código de saída 2
**main.cpp**
#include <iostream>
#include "vector2.hpp"
int main(int, char **)
{
Vector2f test;
//test = (const float)0.0f;
test.dot(test);
return 0;
}
**vector2.hpp**
#ifndef vector2_header
#define vector2_header
#include <cmath>
template <typename number_t>
class Vector2;
template <typename number_t>
Vector2<number_t> operator+(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator+(const Vector2<number_t> &lhs, const number_t rhs);
template <typename number_t>
Vector2<number_t> operator+(const number_t lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator-(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator-(const Vector2<number_t> &lhs, const number_t rhs);
template <typename number_t>
Vector2<number_t> operator-(const number_t lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator*(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator*(const Vector2<number_t> &lhs, const number_t rhs);
template <typename number_t>
Vector2<number_t> operator*(const number_t lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator/(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs);
template <typename number_t>
Vector2<number_t> operator/(const Vector2<number_t> &lhs, const number_t rhs);
template <typename number_t>
Vector2<number_t> operator/(const number_t lhs, const Vector2<number_t> &rhs);
template <typename number_t>class Vector2
{
public:
number_t x;
number_t y;
Vector2() : x(0.), y(0.) {}
Vector2(const number_t x_, const number_t y_) : x(x_), y(y_) {}
Vector2(const Vector2 &v2d) : x(v2d.x), y(v2d.y) {}
friend Vector2 operator+<number_t>(const Vector2 &lhs, const Vector2 &rhs);
friend Vector2 operator+<number_t>(const Vector2 &lhs, const number_t rhs);
friend Vector2 operator+<number_t>(const number_t lhs, const Vector2 &rhs);
friend Vector2 operator-<number_t>(const Vector2 &lhs, const Vector2 &rhs);
friend Vector2 operator-<number_t>(const Vector2 &lhs, const number_t rhs);
friend Vector2 operator-<number_t>(const number_t lhs, const Vector2 &rhs);
friend Vector2 operator*<number_t>(const Vector2 &lhs, const Vector2 &rhs);
friend Vector2 operator*<number_t>(const Vector2 &lhs, const number_t rhs);
friend Vector2 operator*<number_t>(const number_t lhs, const Vector2 &rhs);
friend Vector2 operator/<number_t>(const Vector2 &lhs, const Vector2 &rhs);
friend Vector2 operator/<number_t>(const Vector2 &lhs, const number_t rhs);
friend Vector2 operator/<number_t>(const number_t lhs, const Vector2 &rhs);
Vector2 &operator=(const Vector2 &rhs);
Vector2 &operator=(const number_t &rhs);
Vector2 &operator+=(const Vector2 &rhs);
Vector2 &operator+=(const number_t rhs);
Vector2 &operator-=(const Vector2 &rhs);
Vector2 &operator-=(const number_t rhs);
Vector2 &operator*=(const Vector2 &rhs);
Vector2 &operator*=(const number_t rhs);
Vector2 &operator/=(const Vector2 &rhs);
Vector2 &operator/=(const number_t rhs);
number_t lenghtSq() const;
number_t lenght() const;
number_t dot(const Vector2 &rhs) const;
number_t cross(const Vector2 &rhs) const;
Vector2 &rotate(const number_t rad);
Vector2 rotated(const number_t rad) const;
Vector2 &normalize();
Vector2 normalized() const;
number_t distanceSq(const Vector2 &rhs) const;
number_t distance(const Vector2 &rhs) const;
number_t angle(const Vector2 &rhs) const;
Vector2 absv() const;
};
typedef Vector2<float> Vector2f;#endif // !vector2_header
vector2.cpp
#include "vector2.hpp"
template <typename number_t>
Vector2<number_t> operator+(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs.x + rhs.x, lhs.y + rhs.y);
}
template <typename number_t>Vector2<number_t> operator+(const Vector2<number_t> &lhs, const number_t rhs)
{
return Vector2<number_t>(lhs.x + rhs, lhs.y + rhs);
}
template <typename number_t>Vector2<number_t> operator+(const number_t lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs + rhs.x, lhs + rhs.y);
}
template <typename number_t>Vector2<number_t> operator-(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs.x - rhs.x, lhs.y - rhs.y);
}
template <typename number_t>Vector2<number_t> operator-(const Vector2<number_t> &lhs, const number_t rhs)
{
return Vector2<number_t>(lhs.x - rhs, lhs.y - rhs);
}
template <typename number_t>Vector2<number_t> operator-(const number_t lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs - rhs.x, lhs - rhs.y);
}
template <typename number_t>Vector2<number_t> operator*(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs.x * rhs.x, lhs.y * rhs.y);
}
template <typename number_t>Vector2<number_t> operator*(const Vector2<number_t> &lhs, const number_t rhs)
{
return Vector2<number_t>(lhs.x * rhs, lhs.y * rhs);
}
template <typename number_t>Vector2<number_t> operator*(const number_t lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs * rhs.x, lhs * rhs.y);
}
template <typename number_t>Vector2<number_t> operator/(const Vector2<number_t> &lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs.x / rhs.x, lhs.y / rhs.y);
}
template <typename number_t>Vector2<number_t> operator/(const Vector2<number_t> &lhs, const number_t rhs)
{
return Vector2<number_t>(lhs.x / rhs, lhs.y / rhs);
}
template <typename number_t>Vector2<number_t> operator/(const number_t lhs, const Vector2<number_t> &rhs)
{
return Vector2<number_t>(lhs / rhs.x, lhs / rhs.y);
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator=(const Vector2<number_t> &rhs)
{
if(this != &rhs)
{
x = rhs.x;
y = rhs.y;
}
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator=(const number_t &rhs)
{
x = rhs;
y = rhs;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator+=(const Vector2<number_t> &rhs)
{
x += rhs.x;
y += rhs.y;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator+=(const number_t rhs)
{
x += rhs;
y += rhs;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator-=(const Vector2<number_t> &rhs)
{
x -= rhs.x;
y -= rhs.y;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator-=(const number_t rhs)
{
x -= rhs;
y -= rhs;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator*=(const Vector2<number_t> &rhs)
{
x *= rhs.x;
y *= rhs.y;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator*=(const number_t rhs)
{
x *= rhs;
y *= rhs;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator/=(const Vector2<number_t> &rhs)
{
x /= rhs.x;
y /= rhs.y;
return *this;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::operator/=(const number_t rhs)
{
x /= rhs;
y /= rhs;
return *this;
}
template <typename number_t>number_t Vector2<number_t>::lenghtSq() const
{
return x * x + y * y;
}
template <typename number_t>number_t Vector2<number_t>::lenght() const
{
return sqrt(x * x + y * y);
}
template <typename number_t>number_t Vector2<number_t>::dot(const Vector2<number_t> &rhs) const
{
return x * rhs.x + y * rhs.y;
}
template <typename number_t>number_t Vector2<number_t>::cross(const Vector2<number_t> &rhs) const
{
return x * rhs.x - y * rhs.y;
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::rotate(const number_t rad)
{
const number_t tx(x), dc(cos(rad)), ds(sin(rad));
x = x * dc - y * ds;
y = tx * ds + y * dc;
return *this;
}
template <typename number_t>Vector2<number_t> Vector2<number_t>::rotated(const number_t rad) const
{
Vector2<number_t> nw(*this);
return nw.rotate(rad);
}
template <typename number_t>Vector2<number_t> &Vector2<number_t>::normalize()
{
const number_t len(1. / lenght());
x *= len;
y *= len;
return *this;
}
template <typename number_t>Vector2<number_t> Vector2<number_t>::normalized() const
{
Vector2<number_t> nw(*this);
return nw.normalize();
}
template <typename number_t>number_t Vector2<number_t>::distanceSq(const Vector2<number_t> &rhs) const
{
const number_t dx(x - rhs.x);
const number_t dy(y - rhs.y);
return dx * dx + dy * dy;
}
template <typename number_t>number_t Vector2<number_t>::distance(const Vector2<number_t> &rhs) const
{
const number_t dx(x - rhs.x);
const number_t dy(y - rhs.y);
return sqrt(dx * dx + dy * dy);
}
template <typename number_t>number_t Vector2<number_t>::angle(const Vector2<number_t> &rhs) const
{
Vector2<number_t> nv(normalized());
number_t ang(nv.dot(rhs.normalized()));
if (ang > 1.0)
ang = 1.0;
if (ang < -1.0)
ang = -1.0;
return -acos(ang);
}
template <typename number_t>Vector2<number_t> Vector2<number_t>::absv() const
{
return Vector2<number_t>(abs(x), abs(y));
}
O problema é que aparentemente funciona se copiar o código de **vector2.cpp** para **main.cpp**.
Alguém tem alguma sugestão? Se houver outra fora o problema, também é bem-vinda.
Obs: já tentei compilar pelo terminal também.
Spoiler
mateusgp@debian:~/vscProjects/Math$ g++ -o app main.o vector2.o -lm
/usr/bin/ld: main.o: na função "main":
main.cpp:(.text+0x2a): referência não definida para "Vector2<float>::dot(Vector2<float> const&) const"
collect2: error: ld returned 1 exit status
**CMakeLists.txt**
Spoiler
cmake_minimum_required(VERSION 3.0.0)
project(vector VERSION 0.1.0)
include(CTest)
enable_testing()
include_directories(${PROJECT_SOURCE_DIR})
add_executable(vector main.cpp vector2.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)Discussão (0)
Carregando comentários...