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