[英]Linker failing to find overloaded operator
我正在嘗試為我的一個類重載<<
運算符,但鏈接器始終無法找到重載。 一直在網上搜索我錯過的關於如何聲明和實現運算符重載的任何內容,但對我來說似乎沒有什么特別之處。 有什么想法可以解決這個問題嗎?
Undefined symbols for architecture x86_64:
"memath::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, memath::Vector3 const&)", referenced from:
_main in mecli.cxx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
向量3.h
#include <string>
#include <iostream>
namespace memath {
class Vector3 {
public:
double x;
double y;
double z;
Vector3();
std::string to_string() const;
friend std::ostream& operator<<(std::ostream &strm, const Vector3 &a);
};
};
向量3.cxx
#include <string>
#include <iostream>
#include <sstream>
#include "vector3.h"
using namespace memath;
Vector3::Vector3() : Vector3(0, 0, 0) {}
std::string Vector3::to_string() const {
std::ostringstream r;
r << "Vector3" << "(" << this->x << "," << this->y << "," << this->z << ")";
return r.str();
}
std::ostream& operator<<(std::ostream &strm, const Vector3 &a) {
strm << a.to_string();
return strm;
}
mecli.cxx
#include <iostream>
#include <cstdlib>
#include <string>
#include "vector3.h"
int main(int argc, char** argv) {
memath::Vector3 vec1;
std::cout << vec1 << std::endl;
}
因為Vector3
在命名空間memath
,友元聲明聲明了memath::operator<<
,但您隨后定義了::operator<<
。 所以只需使定義與聲明匹配:
std::ostream& memath::operator<<(std::ostream &strm, const Vector3 &a) {
// ^~~~~~~~
跟進問題,為什么不
using namespace memath;
在這種情況下,似乎在文件頂部很重要,並特別排除此運算符重載?
這對這個運營商來說並不特別。 其實並不是特別針對運營商。 你會得到與函數相同的行為。 並且它並不特別適用於朋友聲明。
所以讓我們在一個更簡單的例子中看到這一點:
namespace ns
{
struct X
{
int foo(int); // => ::ns::X::foo
};
int bar(int); // => ::ns::bar
}
using namespace ns;
int X::foo(int a) { return a + 1; } // (1) => ::ns::X::foo
int bar(int a) { return a * 2; } // (2) => ::bar
就像在您的示例中一樣, foo
按您的預期工作,但bar
是不明確的,就像您的operator<<
。 那么兩者有什么區別呢? 這是一個簡單的解釋:
(1):這是限定名foo
的定義。 X::
是使它合格的原因。 所以在X
搜索foo
。 但什么是X
? X
是不合格的名稱 ID。 所以現在對X
執行不合格的查找。 這意味着在當前命名空間(全局)和using
指令引入的所有命名空間中搜索X
在這種情況下, X
只能在命名空間ns
找到。 所以X::foo
被解析為ns::X::foo
這使得它成為類ns::X
的方法foo
的聲明。
(2) 這是不合格名稱bar
的定義。 由於bar
是非限定的,這被解釋為當前命名空間(全局命名空間)中名稱bar
的聲明。 因為bar
是一個被聲明的新名稱,所以不執行查找。 所以bar
是::bar
的聲明。
請記住,這是一個簡化的解釋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.