簡體   English   中英

朋友模板重載運算符<<:未解析的外部符號

[英]Friend template overloaded operator <<: unresolved external symbol

我的錯誤有問題

錯誤LNK2019無法解析的外部符號“ class std :: basic_ostream>&__cdecl cop4530 :: operator <<(class std :: basic_ostream>&,class rob :: Stack const&)”(?? 6rob @@ YAAAV?$ basic_ostream @ DU在函數_main Project7 c:\\ Users \\ Robrik \\ documents \\ visual studio 2015 \\ Projects \\ Project7 \\ Project7中引用的$ char_traits @ D @ std @@@ std @@ AAV12 @ ABV?$ Stack @ H @ 0 @@ Z) \\ post.obj 1

現在,所有post正在做的就是調用operator<<

報關單

namespace rob {     

template < typename T> class Stack {
    friend std::ostream& operator<< (std::ostream& os, const Stack<T>& a);
    void print(std::ostream& os, char ofc = ' ') const;
private:
    std::vector<T> arr;
};

定義

template < typename T>
inline std::ostream & rob::operator<<(std::ostream & os, const Stack<T>& a)                {     
    return a.print(os, ' ');
}
template<typename T>
inline void rob::Stack<T>::print(std::ostream & os, char c) const
{
    for (int i = 0; i != arr.size(); i++)
    {
        os << c << arr[i];
    }
    os << '\n';
}

它們分別位於.h文件和.hpp ,我要求運算符不是成員函數(用於賦值)。

代碼示例的問題;

template <typename T>
class Stack {
    friend std::ostream& operator<< (std::ostream& os, const Stack<T>& a);
    void print(std::ostream& os, char ofc = ' ') const;
    // ...
};

是否將operator<<聲明為非模板函數。 對於Stack使用的每個T類型,都需要一個非模板operator<< 例如,如果聲明了Stack<int>類型,則必須有一個如下的操作符實現;

std::ostream& operator<< (std::ostream& os, const Stack<int>& a) {/*...*/}

由於未實現,鏈接器無法找到它,並導致您得到錯誤。

作為旁注; gcc關於此的警告如下

warning: friend declaration 'std::ostream& operator<<(...)' declares a non-template function [-Wnon-template-friend]

note: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here)

這可能不是想要的,因為每個瞬間原子都有其自己的實現。

若要更正此問題,可以在Stack類型之前聲明一個模板運算符,然后將其實例化為好友。 語法看起來有些尷尬,但是看起來如下:

// forward declare the Stack
template <typename>
class Stack;

// forward declare the operator <<
template <typename T>
std::ostream& operator<<(std::ostream&, const Stack<T>&);

template <typename T>
class Stack {
    friend std::ostream& operator<< <>(std::ostream& os, const Stack<T>& a);
    // note the required <>        ^^^^
    void print(std::ostream& os, char ofc = ' ') const;
    // ...
};

template <typename T>
std::ostream& operator<<(std::ostream&, const Stack<T>&)
{
  // ... implement the operator
}

上面的代碼將運算符的友好性限制為Stack的對應實例,即, operator<< <int>實例被限制為訪問Stack<int>實例的私有成員。

替代方法包括允許友誼擴展到模板的所有實例。

template <typename T>
class Stack {
    template <typename T1>
    friend std::ostream& operator<<(std::ostream& os, const Stack<T1>& a);
    // ...
};

然后可以在類定義內部或外部內嵌完成operator<<的實現。

您還應該在rob命名空間中實際所屬的函數中聲明函數簽名:

namespace rob {
template <typename T>
class Stack {
    friend std::ostream& operator<< (std::ostream& os, const Stack<T>& a);
};

template < typename T>
std::ostream& operator<< (std::ostream& os, const Stack<T>& a){
    ...
}

除了@LibertyPaul的答案之外,您還需要向朋友std::os...行添加一個template<T> ,以便工作:

namespace rob {

   template <typename T> class Stack {
        friend std::ostream& operator<< (std::ostream& os, const Stack<T>& a) {
              return a.arr.print(os, ' ');
        }
   };

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM