簡體   English   中英

用戶定義類的交換函數從未實例化?

[英]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.

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