[英]Swap function for user-defined class never instantiated?
以下是我正在嘗試創建的更大類並通過提供自己的非成員Friend swap函數使Swappable失敗的簡化示例。
#include <iostream>
#include <utility>
template<typename T>
class Wrapper {
friend void swap(Wrapper& a, Wrapper& b);
public:
Wrapper(T t) : value_(t) {}
const T& operator*() const { return value_; }
private:
T value_;
};
template<typename T>
void swap(Wrapper<T>& a, Wrapper<T>& b) {
using std::swap;
swap(a.value_, b.value_);
}
int main() {
Wrapper<int> w1{5}, w2{10};
std::cout << *w1 << " " << *w2 << std::endl;
swap(w1, w2);
std::cout << *w1 << " " << *w2 << std::endl;
}
嘗試編譯此小型測試程序會導致以下來自clang的鏈接器錯誤(Apple X LLVM版本7.0.2,OS X El Capitan 10.11.3上的clang-700.1.81):
[~/Development/c++_test][16:30:57]$ clang++ --std=c++11 -o SwapTest SwapTest.cc
Undefined symbols for architecture x86_64:
"swap(Wrapper<int>&, Wrapper<int>&)", referenced from:
_main in SwapTest-a978ea.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
為什么盡管在main()中使用了我定義的Wrapper類的模板交換函數,但它卻沒有正確實例化?
friend void swap(Wrapper& a, Wrapper& b);
聲明一個非模板函數swap
,該swap
恰巧采用Wrapper<T>&
參數。 這與您的模板函數swap<T>
不匹配。
一種簡單的解決方法是將朋友聲明為模板函數。
template <typename U>
friend void swap(Wrapper<U>&a, Wrapper<U>& b);
缺點是您所需要的朋友多於您想要的:每個swap
實例都是每個Wrapper<T>
的朋友,而不僅僅是正確的Wrapper<T>
類的朋友。
一種更正確的方法包括在類之前聲明模板函數:
template <class T> class Wrapper;
template <class T>
void swap(Wrapper<T>&, Wrapper<T>&);
template <class T>
class Wrapper
{
friend void swap<>(Wrapper&, Wrapper&);
// ...
只需將您的朋友聲明更改為模板即可:
template<typename T>
class Wrapper {
template<typename U>
friend void swap(Wrapper<U>& a, Wrapper<U>& b);
...
當嘗試編譯您的代碼時,gcc輸出有關此警告
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.