g++:Mac OS X 上的链接器问题 - 体系结构的未定义符号 x86_64
g++: linker issue on Mac OS X - Undefined symbols for architecture x86_64
我之前问过这个问题 here, but got no answer, just a "detour". Now, I am trying to find an actual solution to the problem (stated below). Before anybody says that this question was asked before, I want to say that I tried solutions provided here, here, , and here - 没有任何帮助:(
问题是链接器说 Undefined symbols for architecture x86_64
没有任何 other 警告或错误。调用、完整错误消息和正在编译的代码如下所示。
注意:如果我定义operator<<
内联,问题就消失了,但这不是真正的解决方案,而是绕了个弯路:)
提前谢谢你:)
调用和环境
环境:
- OS: Mac OS X Yosemite (10.10.4)
- XCode: 6.4 (6E35b)
uname -a
: Darwin wireless1x-XXX-XXX-XXX-XXX.bu.edu 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_6
g++ --version
: Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
运行 个参数:
g++ -std=c++11 -lm -stdlib=libc++ tstLinkedList1.cpp -o tstLinkedList1
或
g++ -std=c++11 -lm -stdlib=libstdc++ tstLinkedList1.cpp -o tstLinkedList1
我也尝试在两种情况下添加 -lc++
- 同样的事情:(
错误
编辑: operator<<
重载发生错误,定义在下面LinkedList.hpp
文件的最后
使用 -stdlib=libc++
:
Undefined symbols for architecture x86_64:
"operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, LinkedList<int> const&)", referenced from:
_main in tstLinkedList1-66598f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
使用 -stdlib=libstdc++
:
Undefined symbols for architecture x86_64:
"operator<<(std::ostream&, LinkedList<int> const&)", referenced from:
_main in tstLinkedList1-8d9300.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
代码
LinkedList.hpp:
#pragma once
template <typename T> class LinkedList;
template <typename T>
std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list);
/** Node class
*
* @tparam T template type
*/
template <typename T>
class Node {
private:
T _elem; //!< Stored value
Node<T>* _next; //!< Next element
friend class LinkedList<T>; //!< Friend class
};
/** Singly Linked List
*
* @tparam T template type
*/
template <typename T>
class LinkedList {
public:
LinkedList();
~LinkedList();
std::size_t size() const;
bool empty() const;
const T& front() const;
void addFront(const T& e);
void removeFront();
public:
// Housekeeping
friend std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list);
private:
Node<T>* _head;
std::size_t _size;
};
/** Constructor */
template <typename T>
LinkedList<T>::LinkedList() : _head(nullptr), _size(0) {}
/** Destructor */
template <typename T>
LinkedList<T>::~LinkedList() {
while (!empty()) removeFront();
}
/** Number of elements in the list
*
* @returns std::size_t Number of elements in the list
*/
template <typename T>
std::size_t LinkedList<T>::size() const {
return this->_size;
}
/** Empty?
*
* @returns bool True if empty
*/
template <typename T>
bool LinkedList<T>::empty() const {
return _head == nullptr;
}
/** Get front element (read-only)
*
* @returns T
*/
template <typename T>
const T& LinkedList<T>::front() const {
return _head->_elem;
}
/** Add element in the front of the list
*
* @param e Element to be added
*/
template <typename T>
void LinkedList<T>::addFront(const T& e) {
Node<T>* v = new Node<T>;
v->_elem = e;
v->_next = _head;
_head = v;
_size++;
}
/** Remove the first element */
template <typename T>
void LinkedList<T>::removeFront() {
if (empty()) return;
Node<T>* old = _head;
_head = old->_next;
_size--;
delete old;
}
/** Operator<< for the linked list
*
* @returns std::ostream
* @param LHS->std::ostream
* @param RHS->LinkedList<T>
*/
template <typename T>
std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list) {
os << "TEST";
return os;
}
tstLinkedList1.cpp:
#include <iostream>
#include "LinkedList.hpp"
using namespace std;
int main() {
LinkedList<int> ll1;
ll1.removeFront();
ll1.addFront(1);
std::cout << ll1 << std::endl;
}
好友声明与您认为的不符。它声明了一个非模板函数,而不是您之前声明的模板。您需要的是:
// within LinkedList:
template<typename U>
friend std::ostream& operator<<(std::ostream&, const LinkedList<U>&);
匹配您声明的模板并使那个成为朋友。嗯,整个模板。或者,您也可以使用
// within LinkedList:
friend std::ostream& operator<<<>(std::ostream&, const LinkedList&);
// NOTE: ^^ here you need to add <>
仅将 T
的朋友加为好友(您可以使用 LinkedList
而不是 LinkedList<T>
- 在 class 中没有区别)。
如果你只使用
// within LinkedList:
friend std::ostream& operator<<(std::ostream&, const LinkedList<T>&);
你需要
// within the global namespace
// NOTE: not a template!
std::ostream& operator<<(std::ostream&, const LinkedList<int>&);
使您的示例有效。或者你可以定义 friend operator<<
inline:
// within LinkedList:
friend std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list)
{
// implement me!
return os;
}
并完全删除前向声明。
我之前问过这个问题 here, but got no answer, just a "detour". Now, I am trying to find an actual solution to the problem (stated below). Before anybody says that this question was asked before, I want to say that I tried solutions provided here, here,
问题是链接器说 Undefined symbols for architecture x86_64
没有任何 other 警告或错误。调用、完整错误消息和正在编译的代码如下所示。
注意:如果我定义operator<<
内联,问题就消失了,但这不是真正的解决方案,而是绕了个弯路:)
提前谢谢你:)
调用和环境
环境:
- OS: Mac OS X Yosemite (10.10.4)
- XCode: 6.4 (6E35b)
uname -a
:Darwin wireless1x-XXX-XXX-XXX-XXX.bu.edu 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_6
g++ --version
:Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1 Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn) Target: x86_64-apple-darwin14.4.0 Thread model: posix
运行 个参数:
g++ -std=c++11 -lm -stdlib=libc++ tstLinkedList1.cpp -o tstLinkedList1
或
g++ -std=c++11 -lm -stdlib=libstdc++ tstLinkedList1.cpp -o tstLinkedList1
我也尝试在两种情况下添加 -lc++
- 同样的事情:(
错误
编辑: operator<<
重载发生错误,定义在下面LinkedList.hpp
文件的最后
使用 -stdlib=libc++
:
Undefined symbols for architecture x86_64:
"operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, LinkedList<int> const&)", referenced from:
_main in tstLinkedList1-66598f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
使用 -stdlib=libstdc++
:
Undefined symbols for architecture x86_64:
"operator<<(std::ostream&, LinkedList<int> const&)", referenced from:
_main in tstLinkedList1-8d9300.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
代码
LinkedList.hpp:
#pragma once
template <typename T> class LinkedList;
template <typename T>
std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list);
/** Node class
*
* @tparam T template type
*/
template <typename T>
class Node {
private:
T _elem; //!< Stored value
Node<T>* _next; //!< Next element
friend class LinkedList<T>; //!< Friend class
};
/** Singly Linked List
*
* @tparam T template type
*/
template <typename T>
class LinkedList {
public:
LinkedList();
~LinkedList();
std::size_t size() const;
bool empty() const;
const T& front() const;
void addFront(const T& e);
void removeFront();
public:
// Housekeeping
friend std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list);
private:
Node<T>* _head;
std::size_t _size;
};
/** Constructor */
template <typename T>
LinkedList<T>::LinkedList() : _head(nullptr), _size(0) {}
/** Destructor */
template <typename T>
LinkedList<T>::~LinkedList() {
while (!empty()) removeFront();
}
/** Number of elements in the list
*
* @returns std::size_t Number of elements in the list
*/
template <typename T>
std::size_t LinkedList<T>::size() const {
return this->_size;
}
/** Empty?
*
* @returns bool True if empty
*/
template <typename T>
bool LinkedList<T>::empty() const {
return _head == nullptr;
}
/** Get front element (read-only)
*
* @returns T
*/
template <typename T>
const T& LinkedList<T>::front() const {
return _head->_elem;
}
/** Add element in the front of the list
*
* @param e Element to be added
*/
template <typename T>
void LinkedList<T>::addFront(const T& e) {
Node<T>* v = new Node<T>;
v->_elem = e;
v->_next = _head;
_head = v;
_size++;
}
/** Remove the first element */
template <typename T>
void LinkedList<T>::removeFront() {
if (empty()) return;
Node<T>* old = _head;
_head = old->_next;
_size--;
delete old;
}
/** Operator<< for the linked list
*
* @returns std::ostream
* @param LHS->std::ostream
* @param RHS->LinkedList<T>
*/
template <typename T>
std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list) {
os << "TEST";
return os;
}
tstLinkedList1.cpp:
#include <iostream>
#include "LinkedList.hpp"
using namespace std;
int main() {
LinkedList<int> ll1;
ll1.removeFront();
ll1.addFront(1);
std::cout << ll1 << std::endl;
}
好友声明与您认为的不符。它声明了一个非模板函数,而不是您之前声明的模板。您需要的是:
// within LinkedList:
template<typename U>
friend std::ostream& operator<<(std::ostream&, const LinkedList<U>&);
匹配您声明的模板并使那个成为朋友。嗯,整个模板。或者,您也可以使用
// within LinkedList:
friend std::ostream& operator<<<>(std::ostream&, const LinkedList&);
// NOTE: ^^ here you need to add <>
仅将 T
的朋友加为好友(您可以使用 LinkedList
而不是 LinkedList<T>
- 在 class 中没有区别)。
如果你只使用
// within LinkedList:
friend std::ostream& operator<<(std::ostream&, const LinkedList<T>&);
你需要
// within the global namespace
// NOTE: not a template!
std::ostream& operator<<(std::ostream&, const LinkedList<int>&);
使您的示例有效。或者你可以定义 friend operator<<
inline:
// within LinkedList:
friend std::ostream& operator<<(std::ostream& os, const LinkedList<T>& list)
{
// implement me!
return os;
}
并完全删除前向声明。