【问题标题】:C++ - Why Undefined symbols for architecture x86_64: [duplicate]C ++ - 为什么架构x86_64的未定义符号:[重复]
【发布时间】:2014-05-12 11:22:34
【问题描述】:

我是 C++ 新手,我尝试在 C++ 中学习 template,所以我从 Essential C++ 编写了一个 Matrix 模板类。

这是头文件:

#ifndef __MATRIX__
#define __MATRIX__  

#include <iostream> 

using namespace std;    

template <typename elemType>
class Matrix 
{
    friend Matrix<elemType> operator + ( const Matrix<elemType>&, const Matrix<elemType>& );
    friend Matrix<elemType> operator * ( const Matrix<elemType>&, const Matrix<elemType>& );
public:

    Matrix( int row, int column );
    Matrix( const Matrix& );    

    ~Matrix() { delete [] _matrix; }    

    int row() const { return _row; }
    int column() const { return _column; }  

    Matrix& operator = ( const Matrix& );   

    ostream& print( ostream& ) const;
    void operator += ( const Matrix& ); 

    elemType& operator () (int row, int column ) 
    {
        return _matrix[row * _row + column]; 
    }   

    elemType operator () (int row, int column ) const 
    { 
        return _matrix[row * _row + column]; 
    }   

private:    
    elemType *_matrix;
    int _row;
    int _column;
};  

#endif

这里是源文件:

#include "Matrix.h" 

template <typename elemType>
Matrix<elemType>::Matrix( int row, int column ) :
    _row(row), _column(column)
{
    int size = _row * _column;
    _matrix = new elemType[size];
    for (int i = 0; i < size; ++i)
    {
        _matrix[i] = elemType();
    }
}   

template <typename elemType>
Matrix<elemType>::Matrix( const Matrix& m )
{
    cout << "Matrix( const Matrix& m )" << endl;
    _row = m._row;
    _column = m._column;
    int size = _row * _column;
    _matrix = new elemType[size];
    for (int i = 0; i < size; ++i)
    {
        _matrix[i] = m._matrix[i];
    }
}   

template <typename elemType>
Matrix<elemType>& Matrix<elemType>:: operator = ( const Matrix& m )
{
    cout << "operator = " << endl;
    if( this != &m )
    {
        _row = m._row;
        _column = m._column;
        int size = _row * _column;
        delete [] _matrix;
        _matrix = new elemType[size];
        for (int i = 0; i < size; ++i)
        {
            _matrix[i] = m._matrix[i];
        }
    }
    return *this;
}   

template <typename elemType>
ostream& Matrix<elemType>::print( ostream& os ) const
{
    os << "===print the matrix:===" << endl;
    for (int i = 0; i < _row; ++i)
    {
        for (int j = 0; j < _column; ++j)
        {
            os << _matrix[i * _row + j] << ' ';
        }
        os << endl;
    }
    return os;
}   

template <typename elemType>
void Matrix<elemType>::operator += ( const Matrix& m )
{
    for (int i = 0; i < m.row(); ++i)
    {
        for (int j = 0; j < m.column(); ++j)
        {
            _matrix[i * _row + j] += m(i,j);
        }
    }
}   

template <typename elemType>
Matrix<elemType> operator + ( const Matrix<elemType>& a, const Matrix<elemType>& b )
{
    Matrix<elemType> res(a);
    res += b;
    return res;
}   

template <typename elemType>
Matrix<elemType> operator * ( const Matrix<elemType>& a, const Matrix<elemType>& b )
{
    Matrix<elemType> res( a.row(), b.column() );
    for (int i = 0; i < a.row(); ++i)
    {
        for (int j = 0; j < b.column(); ++j)
        {
            res(i, j) = 0;
            for (int k = 0; k < a.column(); ++k)
            {
                res(i, j) += a(i, k) * b(k, j);
            }
        }
    }
    return res;
}   

template <typename elemType>
inline ostream& operator << ( ostream& os, const Matrix<elemType>& m )
{
    return m.print(os);
}   

int main(int argc, char const *argv[])
{   

    Matrix<int> ima (4,4);
    cout << ima << endl;    

    Matrix<float> fma (4,4);
    cout << fma << endl;    

    float ar[16] = 
    {
        1., 0., 0., 0., 0., 1., 0., 0.,
        0., 0., 1., 0., 0., 0., 0., 1.
    };  

    Matrix<float> fmb(4,4);
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            fmb(i,j) = ar[i*4+j];
        }
    }   

    fma = fmb;  

    cout << fma << fmb << endl; 

    float br[16] = { 1.3, .4, 2.6, 8.2, 6.2, 1.7, 1.3, 8.3,
                    4.2, 7.4, 2.7, 1.9, 6.3, 8.1, 5.6, 6.6 };
    for (int i = 0; i < 4; ++i)
    {
        for (int j = 0; j < 4; ++j)
        {
            fmb(i,j) = br[i*4+j];
        }
    }           

    cout << fma << fmb << endl;     

    fma += fma; 

    cout<< fma << fmb << endl;  

    fma = fma + fma;    

    cout << fma << fmb << endl; 

    return 0;
}

当我在 Sublime 中编译它时,它显示:

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

看来问题出在函数operator +

那么,为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 你永远不会实例化模板。
  • 模板只能在 *.h 文件中声明。有一些变通方法,但您可以通过将所有 *.cpp 代码移动到 *.h 文件来完成这项工作。查看stackoverflow.com/questions/495021/…
  • 您能告诉我们您使用什么编译器(包括版本)和操作系统吗?我在 OS X 10.9 中看到了类似的错误。
  • @user2799037 gcc 4.2.1 OSX10.9.2
  • @Tim 也许这是你真正的问题? stackoverflow.com/q/16352833

标签: c++ templates


【解决方案1】:

类模板中方法的定义应该是

  1. 在标题 OR 中定义
  2. 为 ex 定义。 .impl 文件并包含在声明头 OR
  3. 在 .cpp 文件中显式实例化,在这种情况下,只能使用实例化版本。

出现问题是因为您在源文件中定义方法。

【讨论】:

    【解决方案2】:

    试着像这样开始你的标题

    //declare class and friend operators templates
    template <typename elemType>
    class Matrix;
    
    template <typename elemType>
    Matrix<elemType> operator + ( const Matrix<elemType>&, const Matrix<elemType>& );
    template <typename elemType>
    Matrix<elemType> operator * ( const Matrix<elemType>&, const Matrix<elemType>& );
    

    并像这样在类中声明友元函数

    friend Matrix<elemType> operator + <> ( const Matrix<elemType>&, const Matrix<elemType>& );
    friend Matrix<elemType> operator * <> ( const Matrix<elemType>&, const Matrix<elemType>& );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      • 2015-01-13
      • 2015-06-15
      相关资源
      最近更新 更多