模板函数-类型检查错误- c++

template function - type checking error - c++

本文关键字:错误 c++ 检查 类型 函数      更新时间:2023-10-16

我有这个函数模板

template < class TParam >
bool greaterThan (TParam A, TParam B) {
  if (typeid(TParam) == typeid(string)) {   
    return A.compare(B) > 0;   <--------------- Error
  } else {
    return A > B;
  }
}

但是编译器不允许我对int使用这个。

我在上面显示的地方得到一个编译错误,说
Member reference base type 'int' is not a structure or union.

如果我在int上调用函数,if语句不会运行。

我把它注释掉并检查了。我不知道怎么了

TParamint时,有:

A.compare(B)

您正在尝试调用intcompare方法。这种方法是不存在的。你需要的是模板专门化,这样当类型是特定类型时,你可以让模板做一些特别的事情:

template<class TParam>
bool greaterThan(TParam A, TParam B) {
    return A > B; // this will be called for any type except string because of
                  // our following specialisation
}
// make a specialisation for when the template parameter is string
template<>
bool greaterThan<string>(string A, string B) { 
   return A.compare(B) > 0;
}

语法有点陌生,但如果你仔细阅读它,模板专门化是对模板的一个非常强大的补充。

请注意,string确实有operator<,所以如果你不想的话,你甚至不需要专门化它,但这是一个学习模板专门化的好机会。

您知道您不是在int上调用compare,但编译器不会:您的if在运行时求值。

由于string是模板中唯一的特例,请尝试:

template < class TParam >
bool greaterThan (TParam A, TParam B) {
    return A > B;
}
bool greaterThan(const string& a, const string& b) {
    return a.compare(b) > 0;
}

模板代码是在编译时生成的,所以if()语句还没有执行。

有两个解决方案

a)为int的

提供一个特殊版本的模板

b)不要使用Compare(),并要求struct/classes提供比较操作符

调用模板函数会导致编译器实例化整个函数,导致错误的语句显然不适用于int参数。有几种方法可以区分这两种情况:

首先,对字符串使用greaterThan专门化:

template < class TParam >
bool greaterThan (TParam A, TParam B) {
  return A > B;
}
template<>
bool greaterThan< string > (string A, string B) {
  return A.compare(B) > 0;
}
第二,对字符串使用greaterThan重载:
template < class TParam >
bool greaterThan (TParam A, TParam B) {
  return A > B;
}
bool greaterThan (string const & A, string const & B) {
  return A.compare(B) > 0;
}

在这两个选项中,在编译时决定调用哪个函数,而不是在运行时检查类型。但是请注意,重载接受引用的形参,而专门化接受的形参,因为它必须完全匹配基模板函数的签名。

同样,对于特化,编译器选择的函数有时可能是意外的。由于函数模板只能显式专门化(即不能部分专门化),重载提供了与专门化相关的所有优点而没有缺点。

参见Herb Sutter的"为什么不特化函数模板?"获取更多信息。