ld:在OSX 10.9上找不到架构x86_64的符号

时间:2015-09-05 01:32:26

标签: c++ macos xcode6 stack

我在Xcode 6.2上执行C ++程序,但是我收到了这个错误:

Undefined symbols for architecture x86_64:
  "operator+(Stack1<int> const&, Stack1<int> const&)", referenced from:
      _main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我不确定如何继续解决此问题,我在Stackoverflow.com上检查了其他几个但无法解决我的问题,

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class Stack1;

template <class T>
Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y) {
Stack1<T> z = x;
for (unsigned int i=x.size(); i<(x.size()+y.size()); i++) {
    z.push(y[i]);
}
return z;
}

template <class T>
class Stack1 {
friend Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y);
private: vector <T> elems;
public: bool empty();
void push(const T &item);
T & top();
void pop();
long size();
};

template <class T>
bool Stack1<T>::empty() {
return elems.empty();
}

template <class T>
void Stack1<T>::push(const T &item){
elems.push_back(item);
}

template <class T>
T &Stack1<T>::top(){
   return elems.back();
}

template <class T>
void Stack1<T>::pop() {
if (!elems.empty())
    return elems.pop_back();
}

template <class T>
long Stack1<T>::size() {
return elems.size();
}




int main(int argc, const char * argv[]) {
Stack1 <int> intStack;
Stack1 <float> floatStack;
Stack1 <string> stringStack;
Stack1 <int> a;
Stack1 <int> b;

intStack.push(7);
intStack.push(3);
intStack.push(0);
intStack.push(8);

floatStack.push(0.9);
floatStack.push(4.78);
floatStack.push(2.157);

stringStack.push("test1");
stringStack.push("abc");

while (!intStack.empty()) {
    cout << "Popping from intStack: " << intStack.top() << endl;
    intStack.pop();
}

if (intStack.empty()) {
    cout << "intStack is empty" << endl;
}

while (!floatStack.empty()) {
    cout << "Popping from intStack: " << floatStack.top() << endl;
    floatStack.pop();
}

if (floatStack.empty()) {
    cout << "floatStack is empty" << endl;
}

while (!stringStack.empty()) {
    cout << "Popping from intStack: " << stringStack.top() << endl;
    stringStack.pop();
}

if (stringStack.empty()) {
    cout << "stringStack is empty" << endl;
}

for (int i=0; i<3; i++) {
    a.push(i);
}
for (int i=9; i>5; i--) {
    b.push(i);
}
 //  cout << "Size of a:" << a.size();
Stack1 <int> c;
c = a+b;

while (!c.empty()) {
    cout << "Popping from c: " << c.top() << endl;
    c.pop();
}

return 0;
}

收到此错误:

  error: failed to launch '/Users/User-name/Library/Developer/Xcode/DerivedData/4_TemplatedStack-bmcfhzdrgyhhybajmxvpyuypgmag/Build/Products/Debug/4_TemplatedStack'

3 个答案:

答案 0 :(得分:1)

评论中提到的问题涉及代码中的危险错误,但与链接器问题无关。您需要做的是在<>之后添加operator+

friend Stack1<T> & operator+ <>(const Stack1<T> &x, const Stack1<T> &y);

然后,long size()如果您希望在const个对象上调用它,则需要const

反正。请阅读this guide on operator overloadingoperator+不应返回引用,尤其是返回局部变量。如果有的话,其返回值应为const T。还有其他问题,但我把它作为练习留给你。

答案 1 :(得分:0)

要添加其他答案,由于模板和模板实例化的工作方式,通常单独定义和声明模板没有意义,因为无论如何你的定义都需要放在头文件中才能允许它被实例化。通常,声明和定义是分开的,以便声明在头文件中,而定义在源文件中,它提供两个好处:1。)库的用户只需要头和编译的源,所以保持它们分开允许更快的开发(通过使用预编译的库)2.)在开源之外,实现代码有时可能被隐藏,以便仅分发头。但是,当涉及到模板时,定义和声明都是实例化模板所必需的。因此,通过简单地将声明和定义组合在一起,您将节省相当多的样板和句法烦恼:

// stack1.h
#ifndef STACK1_H
#define STACK1_H

#include <vector>

template<typename T> class Stack1 {
 public:
   Stack1() {}
   Stack1(const Stack1& o) : elements_(o.elements_) {}
   Stack1(const std::vector<T>& elements) : elements_(elements) {}
   virtual ~Stack1() {}

   Stack1 operator+(const Stack1& o) const {
     return Stack1(elements_ + o.elements_);
   }

   void push(const T& item) { elements_.push_back(item); }
   bool empty() const { return elements_.empty(); } 
   T top() const { return elements_.back(); }
   size_t size() const { return elements_.size(); }
 private:
   std::vector<T> elements_;
};


#endif

虽然可以在分离定义和声明时为模板正确指定定义语法,但这样做更容易。如果您继续将定义和声明分开,除了其他建议之外,您还需要为定义使用“inline”关键字,以便在将标题放入标题时防止违反单定义规则(根据需要使用多个源文件中的模板)。

答案 2 :(得分:0)

此处有一些问题可供您定义operator +

的功能
  1. 你在这里定义 template <class T> Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y)operator+是一个模板函数,但在Stack1的类定义中,您说的是 friend Stack1<T> & operator+(const Stack1<T> &x, const Stack1<T> &y); 不是模板函数,这是链接错误的原因。解决方案在Stack1内改为 friend Stack1<T> operator+ <>(const Stack1<T> &x, const Stack1<T> &y);, 详细解释见isocpp FAQ

  2. 请注意,您将返回引用Stack1<T> & operator+,但在函数体内有return z,其中z是局部变量,只要函数调用完成,z被摧毁,对此的提及将是灾难性的。

  3. 你需要改变 for(unsigned int i=x.size(); i<(x.size()+y.size()); i++)for(unsigned int i=0; i<y.size(); i++),因为您推动y[i]i不能超过y.size()

  4. 您还需要为类[]重载运算符Stack1