用于检测C++模板问题的工具

Tool to detect C++ template issues

本文关键字:问题 工具 检测 C++ 用于      更新时间:2023-10-16

我最近花了一些时间在我的C++模板中寻找拼写错误。 g++没有抱怨拼写错误,所以我想知道将来是否有可以检查此类问题的工具?

下面是一个简化的示例,演示了正确的编译。我希望有人抱怨结构假人没有被定义,但似乎模板化类粘液隐藏了这一点。

傅炯:

struct smart {
    int x, y, z;
};
template<typename T> class goo
{
    void barf(T* ptr){}
};
template<typename T> class foo 
{
public:
    foo(){};
private:
    goo<T> x;
};
class bar: public foo<struct dummy>
{
public:
    void do_something(struct smart& thing){}
};

foo.cpp:

#include "foo.h"
int main()
{
    bar a;
    struct smart b;
    a.do_something(b);
    return b.x+b.y+b.z;
}

使用 g++ foo 成功编译.cpp

设置为

最高警告级别的编译器是检测任何C++问题的最佳工具。

我给你的建议是双重的:

1( 将编译器警告级别设置为最高级别。 这将捕获许多较低级别可能保持沉默的错误。

2(使用在做错事时更容易产生编译器错误的编码风格。 例如:

class bar: public foo<struct dummy>
{
public:
    void do_something(struct smart& thing){}
};

老实说,我不知道这段代码是否合法。 我强烈怀疑不是,但看起来您确实在宣布一种新的struct dummy型。 编译器接受它,所以我不确定它是否合法。

这样做会得到很好的服务:

class bar: public foo<dummy>
{
public:
    void do_something(struct smart& thing){}
};

现在,这永远不能解析为新的类型声明,编译器将拒绝它。 这会及早发现您的问题。

如果不使用模板类型参数(示例中就是这种情况(,则代码正常,即使该类型不存在,或者您正在对未调用的成员函数中的类型调用函数。 这是以C++的名义,如果你不使用它,你就不需要为此付费(例如,没有创建新函数(。

这是因为您使用struct dummy如果没有这样的结构退出,编译器被告知自动生成前向声明结构。如果你只使用dummy而不使用struct它就不会这样做,它会抱怨。

Attilla 已经确定了这一点;不需要dummy的定义因此,它可以保持为不完整的类型。 这是一个非常有用的C/C++的功能,因为它有助于信息隐藏以及减少编译时间。

例如:

// Afwd.h
class A;
A * getA ();
void processA(A *);
void printA (A *);

// t.cc
#include "Afwd.h"
void bar ()
{
  A * a = getA ();
  processA (a);
  printA (a);
}

在这里,A客户端无需查看其实现详细信息。 这也具有以下优点:客户端不需要包含定义A所需的标头

为了针对原始示例中的dummy生成错误,必须在此翻译单元中使用定义。

首先,ptr需要以需要完整类型的方式使用,例如通过取消引用:

template<typename T> class goo
{
public:
    void barf(T* ptr){
      *ptr;           
    }
};

这仍然不是问题,因为函数barf没有被调用,因此没有实例化:

template<typename T> class foo 
{
public:
    foo(){
      x.barf (0);
    };
private:
    goo<T> x;
};

此代码现在生成错误。 bar 的构造函数实例化并调用实例化和调用barffoo 定义。