5

Xin chào, tôi nhận được lỗi liên kết LNK2019: biểu tượng bên ngoài chưa được giải quyết khi cố gắng sử dụng toán tử + bị quá tải. Tôi sẽ chỉ cho bạn xem từ lớp học và cách tôi sử dụng nó trong chính. Nếu bạn cần xem thêm, hãy cho tôi biết, tôi sẽ cố gắng giữ cho mọi thứ ngắn gọn.Quá tải + Nhà điều hành Với Mẫu

/** vec.h **/ 
#ifndef __VEC_H_ 
#define __VEC_H_ 

#include <iostream> 
#include <vector> 

namespace xoor{ 

    template<typename T> 
    class vec{ 

    public: 
     inline friend vec<T> operator + (const vec<T>&, const vec<T>&); 
     inline const vec<T>& operator += (const vec<T>&); 

    private: 
     std::vector<T> m_index; 
    }; // Vec. 


    template<typename T> 
    vec<T>& operator + (const vec<T>& a, const vec<T>& b){ 
     vec<T> product = a; 
     product += b; 

     return product; 
    } // Addition. 

    template<typename T> 
    const vec<T>& vec<T>::operator += (const vec<T>& v){ 
     for (unsigned short i =0; i < m_index.size(); ++i){ 
      if (i >= v.size()) 
       break; 
      m_index[i] += v.getIndex()[i]; 
     } 

     return * this; 
    } // Addition Compound. 


} // xoor 

#endif // __VEC_H_ 

Lưu ý rằng tôi cũng đã [] quá tải, vì vậy tôi chỉ truy cập vào các phần của m_index với nó. getIndex() chỉ trả về m_index. Và kích thước() trả về m_index.size()

/** main.cpp **/ 

#include <iostream> 
#include "vec.h" 

void testHook(); 

int main(){ 
    testHook(); 
    system("PAUSE"); 
    return 0; 
} 

void testHook(){ 
    using namespace xoor; 
    vec<double> vA(3); // passing 3 for 3 elements 
    vec<double> vB(3); 

    // v + v 
    std::cout << "\n\tA + B = "; 
    vec<double> vAB(3); 
    vAB = vA + vB; // PRODUCES THE LNK2019 
    vAB.print(std::cout); // Outputs the vec class to the console. 
} 

Thông báo lỗi:

Error 1 error LNK2019: unresolved external symbol "class xoor::vec<double> __cdecl xoor::operator+(class xoor::vec<double> const &,class xoor::vec<double> const &)" ([email protected]@[email protected]@[email protected]@[email protected]) referenced in function "void __cdecl testHook(void)" ([email protected]@YAXXZ) main.obj 

Cập nhật:

Sau đây tại là trực tiếp trên các định nghĩa lớp. Tôi tiếp tục nhận được cùng một lỗi trình liên kết, như được mô tả ở trên.

template<typename T> 
    class vec; 

    template<typename T> 
    vec<T> operator + (const vec<T>&, const vec<T>&); 

Cập nhật 2: Giải pháp.

Bản cập nhật ở trên không chính xác. sbi của giải pháp đã làm việc, tôi chỉ thất bại để mẫu các nhà điều hành như sau.

template<typename T> 
    vec<T> operator +<T> (const vec<T>&, const vec<T>&); 

sbi và david đang thảo luận tại sao tôi sử dụng bạn bè ngay từ đầu. Ban đầu tôi đã sử dụng chúng, bởi vì bạn không thể vượt qua hai tham số cho một toán tử nhị phân quá tải như +, và ngay sau khi bạn bè tìm kiếm như là giải pháp. Khi nó quay ra, bạn vẫn có thể sử dụng toán tử nhị phân khá dễ dàng với một tham số duy nhất. Đây là giải pháp cuối cùng.

// ... 
template<typename T> 
class vec{ 
    public: 
    const vec<T> operator + (const vec<T>&, const vec<T>&)const; 
    // ... 

}; // Vec. 

template<typename T> 
const vec<T> vec<T>::operator + (const vec<T>& v)const{ 
    matrix<T> product = *this; 
    vec(product += v); 
} // Addition. 

Ngoài ra, đối với bất kỳ ai đọc điều này, đáng để kiểm tra ghi chú của sbi ở cuối câu trả lời. Có một số điều tôi đã làm đó là thừa.

Cảm ơn sự giúp đỡ của mọi người. Chúc mừng mã hóa.

+0

Nếu đây là bài tập về nhà (và có vẻ nghi ngờ như vậy), bạn nên thêm thẻ 'bài tập về nhà'. Nhiều người trong chúng ta trả lời các câu hỏi về bài tập ở nhà khác nhau, để bạn học nhiều nhất có thể từ điều này (trong khi các câu hỏi khác thường được hỏi để bất cứ ai hỏi có thể tiếp tục làm những gì họ làm càng nhanh càng tốt). – sbi

Trả lời

7

Để làm bạn với một mẫu, tôi nghĩ rằng bạn sẽ cần phải khai báo mẫu mà trước định nghĩa lớp mà bạn muốn kết bạn với nó. Tuy nhiên, để khai báo này biên dịch, bạn sẽ cần phải chuyển tiếp khai báo mẫu lớp. Vì vậy, điều này sẽ làm việc:

template<typename T> 
class vec; 

template<typename T> 
vec<T> operator + (vec<T>, const vec<T>&); 

template<typename T> 
class vec{ 
public: 
    friend vec<T> operator +<T> (vec<T>, const vec<T>&); 
// ... 

này kết bạn với một trường hợp cụ thể của operator+() hàm mẫu, cụ thể là operator+<T>. (Bạn cũng có thể kết bạn với tất cả các trường hợp của một mẫu:

// no forward declarations necessary 

template<typename T> 
class some_class { 
    template<typename U> 
    friend void f(vec<U>&); 
    // ... 
}; 

Tuy nhiên, điều này ít hữu ích hơn so với phiên bản khác.)

Edit: Một bình luận của David đã cho tôi suy nghĩ (nên đã làm điều này ngay từ đầu) và dẫn đến việc phát hiện ra rằng tờ khai friend là không cần thiết!. operator+ của bạn chỉ sử dụng một hàm public thành viên của vec (operator+=) và do đó không cần phải là friend của lớp học. Vì vậy, ở trên sẽ đơn giản hóa để

template<typename T> 
class vec{ 
public: 
    // ... 
}; 

template<typename T> 
vec<T> operator + (vec<T> a, const vec<T>& b){ 
    a += b; 
    return a; 
} 

Dưới đây là một nhiều hơn vài lưu ý:

  • operator+() (mà bạn độc đáo được thực hiện trên đầu trang của operator+=(), BTW) nên tranh luận trái của nó mỗi bản sao.
  • Đừng tuyên bố chức năng như inline, xác định họ như vậy.
  • operator+=() trả về tham chiếu không const, bởi vì mọi người mong đợi f(m1+=m2) để hoạt động ngay cả khi f() lấy tham số của nó là tham chiếu không phải là const.
  • Bên trong mẫu lớp, ở hầu hết các địa điểm, bạn có thể bỏ qua danh sách tham số mẫu khi tham chiếu đến lớp học. Vì vậy, bạn có thể nói vec& operator += (const vec&);. (Bạn không thể làm điều này bên ngoài của mẫu, mặc dù - ví dụ, khi xác định các nhà điều hành mà bên ngoài của lớp.)
  • Một std::vector 's loại chỉ số được đánh vần std::vector<blah>::size_type, khôngunsigned short.
+0

Cảm ơn bạn đã trả lời và lấy mẫu. Thật không may điều này đã không làm việc. Tôi sẽ tiếp tục thử một vài thứ. Nếu bạn nghĩ về bất cứ điều gì, tôi sẽ kiểm tra lại thường xuyên. – Xoorath

+0

@Xoorath: "Nó không hoạt động" quá mơ hồ để có thể nói bất cứ điều gì. (Tôi thực sự có một phiên bản ở đây biên dịch và liên kết với VC, vì vậy tôi biết nó hoạt động theo nguyên tắc.) – sbi

+0

Xin lỗi bạn thân. Một giây. Tôi sẽ cập nhật đoạn mã của mình. – Xoorath

7

Kiểu trả về ở đây:

inline friend vec<T> operator + (const vec<T>&, const vec<T>&); 

Không phù hợp ở đây:

template<typename T> 
    vec<T>& operator + (const vec<T>& a, const vec<T>& b){ 
     vec<T> product = a; 
     product += b; 

     return product; 
    } // Addition. 
+0

Ngoài ra, nó không phải là hàm __declarations__ cần được đánh dấu là 'inline', nhưng hàm __definitions__. Vì vậy, nó là 'người bạn vec operator + (const vec &, const vec &); 'và' const vec & operator + = (const vec &); ', nhưng' inline vec operator + (const vec &, const vec &) {...} 'và' inline const vec & toán tử + = (const vec &) {...} '. Oh, và lý do để có '+ =' trả về 'const vec &' là gì? Tôi nghĩ rằng đây nên là một tham chiếu không phải ''. – sbi

+1

Một điều nữa (thực sự, tôi nên có câu trả lời của riêng mình ...): Vì toán tử bên trái toán hạng sẽ được sao chép ngay lập tức, đối số đó phải được chuyển qua bản sao thay vì tham chiếu 'const'. Điều này được sử dụng để được nhìn thấy khác nhau (sao chép là một chi tiết thực hiện và không nên rò rỉ vào giao diện), nhưng người thông minh phát hiện ra rằng làm cho bản sao khi đi qua các đối số cho trình biên dịch một vài cơ hội tối ưu hóa hơn (chẳng hạn như bỏ việc sao chép khi toán hạng là một tạm thời mà sẽ bị phá hủy anyway). – sbi

+0

Cảm ơn bạn rất nhiều. – Xoorath

Các vấn đề liên quan