【问题标题】:Function template for string and int in C++C++中字符串和int的函数模板
【发布时间】:2013-04-17 14:02:01
【问题描述】:

我想要一个函数模板,它接受一个向量和一个元素,并返回该元素在向量中的位置。我希望这个函数适用于 int 和 std::string 类型。这是函数模板定义:

template<class T>
int findElement(const vector<T> &vec, const T &ele)
{
    for(size_t i = 0; i < vec.size(); i++)
    {
        if(typeid(ele) == typeid(std::string))
        {
            if(ele.compare(vec[i]) == 0)
                return i;
        }
        else
        {
            if(ele == vec[i])
                return i;
        }
    }
    return -1;
}

如您所见,我最初是在检查类型,以便使用适当的比较方法。当我使用 std::string 类型参数调用时,这很好用,但是当我使用双精度类型时,它会给出以下错误:

 error C2228: left of '.compare' must have class/struct/union

see reference to function template instantiation 'int findElement<double>(const std::vector<_Ty> &,const T &)' being compiled

我该如何解决这个问题?

谢谢, 拉克什。

【问题讨论】:

  • std::string 定义了 == 运算符!
  • 替代搜索 - iter = std::find(vec.begin(), vec.end(), ele);?
  • 另外,如果你想要两种不同的行为 - 只需编写两个不同的函数。 :-)
  • 顺便说一句,您不应该真正使用int 作为通用实用程序代码中向量的大小。有人可以在 64 位机器上创建一个大于 INT_MAX 的向量。

标签: c++ templates


【解决方案1】:

std::string 具有 operator ==,但是,如果您想从 T 调用不同的方法 - 您应该专门化或重载函数。 Typeid 无能为力,因为它是运行时类型识别。

重载示例

template<class T>
int findElement(const vector<T> &vec, const T &ele)
{
    for(size_t i = 0; i < vec.size(); i++)
    {
        if(ele == vec[i])
             return i;
    }
    return -1;
}

int findElement(const vector<string>& vec, const string& ele)
{
   for (size_t i = 0; i < vec.size(); ++i)
   {
      if (ele.compare(vec[i]) == 0)
          return i;
   }
   return -1;
}

另外,您可以使用function overloading 仅用于比较,因为循环是相同的。

【讨论】:

    【解决方案2】:

    您应该从不在使用模板时检查typeidstd::string 以预期的方式定义了==,所以使用它!

    template<class T>
    int findElement(const vector<T> &vec, const T &ele)
    {
        for(size_t i = 0; i < vec.size(); i++)
        {
            if(ele == vec[i])
                return i;
        }
        return -1;
    }
    

    一般来说,如果您需要针对特定​​类型对模板化函数进行特殊处理,请使用 模板特化

    template<class T>
    int findElement(const vector<T> &vec, const T &ele) {
        for(size_t i = 0; i < vec.size(); i++) {
            if(ele == vec[i])
                return i;
        return -1;
    }
    
    template<>
    int findElement<std::string>(const vector<std::string> &vec, const std::string &ele) {
        for(size_t i = 0; i < vec.size(); i++) {
            if(ele.compare(vec[i]) == 0)
                return i;
        }
        return -1;
    }
    

    【讨论】:

    • +1 表示不使用 typeid。请务必了解运行时和编译时反射机制之间的区别。运行时反射通常不是 C++ 的方式。
    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多