【问题标题】:C++:Use user-defined generic functionsC++:使用用户定义的泛型函数
【发布时间】:2012-04-07 12:46:28
【问题描述】:

我现在正在阅读《C++ 标准库》。我发现第 5.7 章有些混乱。 众所周知,我们可以编写自己的函数和算法来处理集合的元素。当然这些操作也可能是通用的。 让我们看一个例子。下面的代码定义了一个通用函数,它打印一个可选字符串,后跟传递容器的所有元素。

template <class T>
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "")
{
    typename T::const_iterator pos;
    for(pos = col1.begin();pos != col1.end();++pos)
        cout << *pos << " ";
    cout << endl;
}

而pos被声明为具有传递容器类型的迭代器类型,typyname必要的指定 const_iterator 是一个类型,而不是 T 类型的值。

我有几个问题:

(1)当我删除代码中的typename时,效果很好。 见以下代码:

#include <iostream>
#include <vector>
#include <set>
#include <algorithm>

using namespace std;

int square (int value)
{
    return value*value;
}

template <class T>
inline void PRINT_ELEMENTS(const T& col1,const char *optcstr = "")
{
    /*typename T::const_iterator pos;*/
    T::const_iterator pos;

    for(pos = col1.begin();pos != col1.end();++pos)
        cout << *pos << " ";
    cout << endl;
}

int main()
{
    set<int>    coll1;
    vector<int> coll2;

    // insert elements from 1 to 9 into coll1
    for (int i=1; i<=9; ++i) {
        coll1.insert(i);
    }
    /*PRINT_ELEMENTS(coll1,"initialized: ");*/

    // transform each element from coll1 to coll2
    // - square transformed values
    transform (coll1.begin(),coll1.end(),    // source
                    back_inserter(coll2),    // destination
                    square);                      // operation

    PRINT_ELEMENTS(coll2,"squared:     ");
}

效果很好。它的输出是:

为什么?typename 不是必需的吗? 而且我不太了解它在这里的作用。 谁能给我翻译一下?

(2) 为什么我不能使用 vector::iterator 来输出这样的元素:

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    set<int> intSet;
    vector<int> intVector2;

    for (int i = 1;i <= 10;++i)
        intSet.insert(i);

    transform(intSet.begin(),intSet.begin(),
        back_inserter(intVector2),
        negate<int>());

    vector<int>::iterator iter = intVector2.begin();
    for(;iter != intVector2.end();++iter)
        cout << *iter << endl;
}

它什么也不输出。我使用 Visual Studio 2008 运行我的代码。 有人可以帮我吗?非常感谢。

【问题讨论】:

    标签: c++ generics stl iterator generic-programming


    【解决方案1】:

    typename 不是必需的,因为某些版本的 Visual Studio 不符合标准。较新的版本和其他编译器对此更加严格,如果没有它,您的代码将无法在那里编译。

    您的第二个示例不起作用,因为您传递了 begin()begin(),而不是 begin()end()

    transform(intSet.begin(),intSet.begin(),
    

    哎呀。

    【讨论】:

      【解决方案2】:

      (1)

      typename 有助于在某些情况下将其操作数作为类型消除歧义。

      最突出的似乎是在类声明的范围内:

      class X
      {
          ...
          typename Y::Z w; // necessary
      };
      

      (2)

      有错别字...

      -    transform(intSet.begin(),intSet.begin(),
          back_inserter(intVector2),
          negate<int>());
      
      
      +    transform(intSet.begin(),intSet.end(),
          back_inserter(intVector2),
          negate<int>());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        • 2016-01-12
        • 2017-04-01
        相关资源
        最近更新 更多