簡體   English   中英

按類型專門化模板類成員函數

[英]Specializing a template class member function by type

我試圖通過其模板參數的類型特征來專門針對模板化類的成員函數,但是我的前向聲明顯然是錯誤的。 有簡單的解決方法嗎?

#include <type_traits>

template <typename T>
class TTest{
public:
  T data;

  // edited to comment this out, template<typename U>
  bool operator !=(const TTest& other) const;
};

template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, bool>::type
TTest<T>::operator !=(const TTest<T>& other) const{
  return true;
}

template<typename T>
bool TTest<T>::operator !=(const TTest<T>& other) const{
  return false;
}

int main(){
  TTest<size_t> t1;
  TTest<int> t2;
}

lang告訴我:

templateTest.cpp:13:11: error: out-of-line definition of 'TTest::operator!='
  differs from the declaration in the return type
TTest<T>::operator !=(const TTest<T>& other) const{
          ^
templateTest.cpp:8:8: note: previous declaration is here
  bool operator !=(const TTest& other) const;
       ^
1 error generated.

似乎整個enable_if shebang是函數簽名的一部分(或者我不太了解錯誤)。 如果將其更改為,我可以使代碼進行編譯並按您希望的方式運行

template <typename T>
class TTest{
public:
  T data;

  template<typename U>
  typename std::enable_if<std::is_unsigned<U>::value, bool>::type
  operator !=(const TTest<U>& other) const;

  template<typename U>
  typename std::enable_if<not std::is_unsigned<U>::value, bool>::type
  operator !=(const TTest<U>& other) const;
};

template <typename T>
template <typename U>
typename std::enable_if<std::is_unsigned<U>::value, bool>::type
TTest<T>::operator !=(const TTest<U>&) const{
  return true;
}

template <typename T>
template <typename U>
typename std::enable_if<not std::is_unsigned<U>::value, bool>::type
TTest<T>::operator !=(const TTest<U>&) const{
  return false;
}

現場演示 當然,如果您內聯定義這些運算符,則此操作將減少很多重復。

更好的方法可能是基於T的特性將操作員邏輯的不同私有實現分派。 這將從代碼中刪除所有SFINAE詳細信息。

template <typename T>
class TTest{
public:
  T data;

  bool operator!=(const TTest& other) const
  {
      return not_equal_to(other, typename std::is_unsigned<T>::type());
  }

private:
  bool not_equal_to(TTest const&, std::true_type) const
  {
      return true;
  }

  bool not_equal_to(TTest const&, std::false_type) const
  {
      return false;
  }
};

現場演示

您聲明了類模板的成員函數模板,並且嘗試將其專門化為成員函數。 那不會飛。 同樣,返回類型不同,盡管最終對同一事物進行求值。

我不知道您要嘗試什么,因為甚至沒有推斷出成員函數模板的類型U (您的意思是該參數的類型為TTest<U>嗎?)。 如果您想基於特征來專門化您的成員,我想您要么不需要重載運算符,要么使用其他方法(例如,將實現委派給專門的類模板):

#include <iostream>
#include <type_traits>

template <typename T>
class TTest{
public:
  T data;

  template<typename U>
  typename std::enable_if<!std::is_unsigned<U>::value, bool>::type
  operator !=(const TTest<U>& other) const;

  template<typename U>
  typename std::enable_if<std::is_unsigned<U>::value, bool>::type
  operator !=(const TTest<U>& other) const;
};

template <typename T>
template<typename U>
typename std::enable_if<!std::is_unsigned<U>::value, bool>::type
TTest<T>::operator !=(const TTest<U>& other) const {
    return true;
}

template <typename T>
template<typename U>
typename std::enable_if<std::is_unsigned<U>::value, bool>::type
TTest<T>::operator !=(const TTest<U>& other) const {
    return false;
}

int main(){
  TTest<unsigned int> t1;
  TTest<int> t2;
  std::cout << std::boolalpha
            << "t1 != t1: " << (t1 != t1) << '\n'
            << "t1 != t2: " << (t1 != t2) << '\n'
            << "t2 != t1: " << (t2 != t1) << '\n'
            << "t2 != t2: " << (t2 != t2) << '\n';
}

標簽分發是執行此操作的干凈方法:

template <typename T>
class TTest{
  bool not_equal( const ITest& other, std::true_type /* is unsigned */ ) const;
  bool not_equal( const ITest& other, std::false_type /* is unsigned */ ) const;
public:
  T data;

  bool operator !=(const TTest& other) const {
    return not_equal( other, std::is_unsigned<T>() );
  }
};

現在只需實現兩個TTest<T>::not_equal重載。 只有給定的T實際調用的那個才會通過基本解析來編譯。

暫無
暫無

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

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