繁体   English   中英

以stl容器作为输入的功能模板

[英]function template with stl container as an input

我收到编译错误是以下代码。 我认为这应该在c ++中起作用。有人可以帮助我了解这里的问题吗。

template < typename elem_type>
elem_type *find2( std::vector<elem_type>& vec, elem_type value) {
    for ( int i = 0; i < vec.size(); ++i) {
        if ( vec[i] == value ) {
            return &vec[i];
        }
    }
    return 0;
}
int main( int argc, char **argv) {
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    std::vector<int> vec( arr, arr+10);     
    int value = 9;
    int *ptr1 = find2(vec,value);
}

以下是编译错误

1>          d:\personal\work\find\find\find.cpp(25) : see reference to function template instantiation 'elem_type *find2<int>(std::vector<_Ty> &,elem_type &)' being compiled
1>          with
1>          [
1>              elem_type=int,
1>              _Ty=int
1>          ]

编译器是Visual Studio 11

最好使用与容器中使用的索引相同类型的变量。 在这种情况下,您需要一个size_t或一个size_type 它们与向量的sizeoperator []函数中使用的类型相对应。

for (size_t i = 0; i < myVector.size(); ++i)
{
    myVector[i]++;
}

如果您需要反向迭代,只需维护一个内部索引。

for (size_t i = 0; i < myVector.size(); ++i)
{
    size_t j = myVector.size() - i - 1;
    myVector[j]++;
}

如果您需要执行带符号的数学运算,请再次维护内部转换。

for (size_t i = 0; i < myVector.size(); ++i)
{
    int j = (int)i;
    myVector[i] += j;
}

您的基本问题是要混合有符号和无符号整数。 您的索引变量是有符号类型,但是向量的size()成员函数返回无符号类型。 这样的混合类型可能会导致错误。 如果将诸如-1之类的有符号值分配给无符号变量,则通常会得到非常大的值。

遍历标准库容器的惯用方式是使用标准库迭代器。

for (std::vector<elem_type>::iterator it=vec.begin(); it<vec.end(); ++it)
{
    if ( *it == value ) {
        return &(*it);
    }
}

在这一行,

    for ( int i = 0; i < vec.size(); ++i ) {

您正在将带符号的int变量ivec.size()的无符号的size_t结果进行vec.size()

编译器发出警告,因为面对C ++中的隐式提升 ,这种比较是不安全的。 i被提升为size_t 如果i (假设)为负,那将产生非常大的价值,并因此产生意想不到的比较结果。

一个简单的方法是

    #include <stddef.h>
    typedef ptrdiff_t Size;
    typedef Size Index;

然后做例如

    for ( int i = 0; i < Size( vec.size() ); ++i ) {

您可能会得到至少一个答案,建议您看似简单一些

    for ( size_t i = 0; i < vec.size(); ++i ) {

但这是有问题的,原因是编译器警告过同样的原因:使用无符号整数作为数字可能会导致非常奇怪和意外的结果,错误的结果,这是由于隐式提升以及通常从负数到无符号的转换,反之亦然。

比上面的转换更好,定义一个countOf函数,例如

    template< class Container >
    Size countOf( Container const& c ) { return v.size(); }

    template< class Elem, Size n >
    Size countOf( Elem (&)[n] ) { return n; }

然后只写

    for ( int i = 0; i < countOf( vec ); ++i ) {

最好不要忘记建立索引并使用迭代器:

    for ( auto it = vec.begin(); it != vec.end(); ++it ) {

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM