C++ 按类型专门化模板类成员函数

C++ 按类型专门化模板类成员函数,c++,templates,specialization,C++,Templates,Specialization,我试图通过模板类的模板参数的类型特征来专门化模板类上的成员函数,但我的转发声明显然不正确。有简单的解决办法吗 #include <type_traits> template <typename T> class TTest{ public: T data; // edited to comment this out, template<typename U> bool operator !=(const TTest& other) co

我试图通过模板类的模板参数的类型特征来专门化模板类上的成员函数,但我的转发声明显然不正确。有简单的解决办法吗

#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;
}
#包括
模板
类测试{
公众:
T数据;
//编辑以注释掉此模板
布尔运算符!=(常数测试和其他)常数;
};
模板
typename std::enable_if::type
操作员=(常数测试和其他)常数{
返回true;
}
模板
操作员=(常数测试和其他)常数{
返回false;
}
int main(){
t试验t1;
t试验t2;
}
叮当声告诉我:

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.
templateTest.cpp:13:11:错误:“TTest::operator!=”的定义不正确
与返回类型中的声明不同
操作员=(常数测试和其他)常数{
^
templateTest.cpp:8:8:注意:前面的声明在这里
布尔运算符!=(常数测试和其他)常数;
^
生成1个错误。

您声明了类模板的一个成员函数模板,并试图将其专门化为一个成员函数。这是行不通的。此外,返回类型不同,尽管最终的计算结果相同

我不知道您试图尝试什么,因为成员函数模板的类型
U
(您的意思是参数的类型为
TTest
?)。如果您想基于特征专门化您的成员,我认为您不需要重载运算符或使用不同的方法(例如,将实现委托给专门的类模板):

#包括
#包括
模板
类测试{
公众:
T数据;
模板
typename std::enable_if::value,bool>::type
操作员!=(常数测试和其他)常数;
模板
typename std::enable_if::type
操作员!=(常数测试和其他)常数;
};
模板
模板
typename std::enable_if::value,bool>::type
TTest::运算符!=(常数TTest和其他)常数{
返回true;
}
模板
模板
typename std::enable_if::type
TTest::运算符!=(常数TTest和其他)常数{
返回false;
}
int main(){
t试验t1;
t试验t2;

std::cout您声明了类模板的一个成员函数模板,并试图将其专门化为一个成员函数。这是行不通的。此外,返回类型不同,尽管最终的计算结果相同

我不知道您试图尝试什么,因为成员函数模板的类型
U
(您的意思是参数的类型为
TTest
?)。如果您想基于特征专门化您的成员,我认为您不需要重载运算符或使用不同的方法(例如,将实现委托给专门的类模板):

#包括
#包括
模板
类测试{
公众:
T数据;
模板
typename std::enable_if::value,bool>::type
操作员!=(常数测试和其他)常数;
模板
typename std::enable_if::type
操作员!=(常数测试和其他)常数;
};
模板
模板
typename std::enable_if::value,bool>::type
TTest::运算符!=(常数TTest和其他)常数{
返回true;
}
模板
模板
typename std::enable_if::type
TTest::运算符!=(常数TTest和其他)常数{
返回false;
}
int main(){
t试验t1;
t试验t2;

std::cout如果
shebang是函数签名的一部分(或者我真的不理解错误),那么整个
enable_似乎都是如此。如果我将代码更改为

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;
}

如果
shebang是函数签名的一部分(或者我真的不理解错误),那么整个
enable\u似乎都是启用的。如果我将代码更改为

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;
}

标签分派是一种干净的方法:

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>() );
  }
};
模板
类测试{
bool not_equal(const ITest&other,std::true_type/*为无符号*/)const;
bool not_equal(const ITest&other,std::false_type/*为无符号*/)const;
公众:
T数据;
布尔运算符!=(常数测试和其他)常数{
返回值不相等(其他,std::is_unsigned());
}
};

现在只需实现两个
TTest::not_equal
重载。只有为给定的
T
实际调用的重载将通过基本解析进行编译。

标记分派是一种干净的方法:

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>() );
  }
};
模板
类测试{
bool not_equal(const ITest&other,std::true_type/*为无符号*/)const;
bool not_equal(const ITest&other,std::false_type/*为无符号*/)const;
公众:
T数据;
bool运算符!=(常量测试和其他)常量{
返回值不相等(其他,std::is_unsigned());
}
};

现在只需实现两个
TTest::not_equal
重载。只有为给定
T
实际调用的重载将通过基本解析进行编译。

此代码没有任何意义。成员模板对模板参数没有依赖性,因此没有什么需要专门化的。您知道
const-TTest&other
在rmember模板中的意思是
const-TTest&other
?您不能部分地专门化函数模板。如果您想要无符号t和无符号t的版本,则需要重载+SFINAE或部分地专门化整个类模板。@Kerrek I简化了代码。根据t是有符号的还是无符号的运算符!=的实现将不同。编辑:哎呀,typename U位是一次尝试修复它时留下的。我将编辑QT。此代码没有意义。成员模板不依赖于模板参数,因此没有什么需要专门化的。您知道
const-TTest&other
表示
const-TTest&other吗
在rmember模板中?不能部分专门化函数模板。如果要为无符号t和无符号t创建版本,则需要重载+SFINAE或部分专门化整个类模板。@Kerrek我简化了代码。具体取决于