【问题标题】:What is wrong with this implementation of static template function? [duplicate]这个静态模板函数的实现有什么问题? [复制]
【发布时间】:2012-09-13 14:30:36
【问题描述】:

可能重复:
Where and why do I have to put the “template” and “typename” keywords?

我正在学习模板函数。我正在尝试实现一个清除指针列表的静态模板函数。为此,我想使用模板。这是我的代码:

#include <cstdio>
#include <list>
using namespace std;

class util
{
public:
    template <class ARG>
    static void CleanPointers(list<ARG> &mylist) {
        list<ARG>::iterator it;
        for (it = mylist.begin(); it != mylist.end(); it++)
        {
            ARG obj = (ARG) *it;
            delete obj;
        }
        mylist.clear();
    };

    util();
    ~util();
};

int main()
{
    list<int*> mylist;
    mylist.push_back(new int(1));
    mylist.push_back(new int(2));
    util::CleanPointers<int*>(mylist);
    return 0;
}

我收到了以下编译错误消息,但我不明白这里有什么意义。 :) 为什么需要我放;之前?

prog.cpp: In static member function ‘static void util::CleanPointers(std::list<ARG,         std::allocator<_Tp1> >&)’:
prog.cpp:10: error: expected `;' before ‘it’
prog.cpp:11: error: ‘it’ was not declared in this scope
prog.cpp: In static member function ‘static void util::CleanPointers(std::list<ARG,     std::allocator<_Tp1> >&) [with ARG = int*]’:
prog.cpp:28:   instantiated from here
prog.cpp:10: error: dependent-name ‘std::list::iterator’ is parsed as a non-type,   but instantiation yields a type
prog.cpp:10: note: say ‘typename std::list::iterator’ if a type is meant

【问题讨论】:

  • 我认为使用短语“清除指针”是一个非常糟糕的主意,因为它没有任何意义并且可能会产生灾难性的误导。正确的概念是“删除一个动态分配的对象(通过在指向该对象的指针上调用delete)”。
  • @KerrekSB,是的!你说的对。我会改变的。

标签: c++ templates static


【解决方案1】:

需要类型名,因此:

typename list<ARG>::iterator it;

不过,这并不是代码的唯一错误。为什么在删除之前要转换为 int ?当它不是指向整数的指针集合时,这是一个糟糕的错误。如果你打算这样做,你应该通过正确的指针类型删除。

此外,您可以进行部分专业化,因为 ARG 必须是指针类型。

C++ FAQ about templates。我建议阅读所有这些内容。

另请参阅关于强制转换为何邪恶的常见问题解答,它还可能解释删除会发生什么。

【讨论】:

  • 你能解释一下为什么吗?或者给我一些阅读链接。
  • 我这样做是因为我将 ARG 更改为 int* 并且代码有效,而当我改回来时,我并没有全部更改。 (这是我的代码:ideone.com/L6mQY)我应该编辑我的问题,因为它不是我的主要问题吗?这只是一个错字。
  • delete 和 C 中的 free 不一样,它不只是释放内存,还删除了下面的对象。因此,如果您的指针不是 int*,则转换为 int* 是未定义的行为。
【解决方案2】:

Dependent names:

typename list<ARG>::iterator it;

【讨论】:

  • 这不是问题的答案。哇,看着你的大部分答案,我假设你真的在按数量而不是按质量表示的网站上。您的许多答案一开始也会受到抨击(当之无愧),而且实际上只是想了半天。
  • @phresnel 答案包含修复和解释链接。我看不出这与其他有什么不同。你还会做什么?
  • 靠运气(即您对一个帖子的傲慢评论,然后在另一个帖子中的错误和愚蠢的答案,与您的傲慢相矛盾)我现在只看了您的答案。 “其他人也这样做了”不是聪明人的论据。但相信我,我也会批评和鼓励其他人。你的帖子的问题:它本身并没有教提问者:问:“这个实现有什么问题[...]?”,答:“从属名称!”,问:“从属名称错了?!” .一般来说,关于 SO 的答案应该是:a)答案,b)自包含(不要依赖链接腐烂不会发生)。你的答案都不是。
  • @phresnel 那么,无论如何 - 投反对票并添加你自己的。
  • @phresnel & 我只说了其他答案,因为你似乎在瞄准我——在你的书中,这显然是智慧的标志。
【解决方案3】:

list&lt;ARG&gt;::iterator 是依赖类型:

typename list<ARG>::iterator it;

Where and why do I have to put the "template" and "typename" keywords?

【讨论】:

    【解决方案4】:

    我认为您的主要错误是在某处定义 var 'it' 的类型。 在错误 10 之后,所有编译器错误都是垃圾,因为编译器尝试使用非类型 var 完成 for 循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-02
      • 2021-08-15
      • 2021-10-17
      • 2011-09-28
      • 2011-12-14
      • 2017-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多