【问题标题】:"class template has already been declared as a non-class template"“类模板已被声明为非类模板”
【发布时间】:2011-10-13 02:38:24
【问题描述】:

嘿,当我在后面的代码中留下namespace sf{ 声明时,我遇到了这个奇怪的错误:

1>c:\libraries and headers\sfml\sfml-1.6-sdk-windows-vc2008\sfml-1.6\include\sfml\graphics\body.h(70): error C2989: 'sf::Body' : class template has already been declared as a non-class template
1>c:\libraries and headers\sfml\sfml-1.6-sdk-windows-vc2008\sfml-1.6\include\sfml\graphics\body.h(11): error C3856: 'sf': class is not a class template

代码在过去 3 周内不是模板类时运行良好,具有相同的 sf::Body 类名;我最近刚刚更改它以使其更灵活。我不能在命名空间内声明模板类吗?

代码如下:

#include <SFML/Graphics.hpp>
#include <vector>
#include <math.h>
#include <cmath>

namespace sf{ //when i take this out and the closing bracket the code runs fine

    template<typename drawable>     
class Body : public sf::Drawable{ 

    private:
        sf::Vector2f MoveVal;
        std::vector<drawable> Drawables;

    public:
        Body(const Vector2f& Position = Vector2f(0, 0), const Vector2f& Scale = Vector2f(1, 1), float Rotation = 0.f, const Color& Col = Color(255, 255, 255, 255)){
            SetPosition(Position);
            SetScale(Scale);
            SetRotation(Rotation);
            SetColor(Col);};

// Overide Drawable Functions To Detect any Movement
        void SetX(float X){
            MoveVal.x += X - GetPosition().x;
            Drawable::SetX(X);};

        void SetY(float Y){
            MoveVal.y += Y - GetPosition().y;
            Drawable::SetY(Y);};

// Regular Functions
        void AddObject(drawable& Object){
            Object.Move(GetX(),GetY());
            Drawables.push_back(Object);};

        void DestroyObject(unsigned short Index){
            Drawables.erase(Drawables.begin()+Index);};

        void Clear(){
            Drawables.clear();};

        drawable& GetObject(unsigned short index) 
            {return Drawables[index];};

        unsigned int GetNumbObjects() 
        {return Drawables.size();};

        void Draw(sf::RenderTarget& target){
            for(unsigned short I=0; I<Drawables.size(); I++){
                //Body offset
                Drawables[I].SetPosition( 
                    Drawables[I].GetPosition().x + MoveVal.x,
                    Drawables[I].GetPosition().y + MoveVal.y);
            }                                                   // TODO: add tint based on overall Body Color

            target.Draw(*this); 

            //Reset all the Change Values
            MoveVal.x=0;
            MoveVal.y=0;
        };

        void Render(sf::RenderTarget& target) const{
            for(int I=0; I< Drawables.size(); I++)
                Drawables[I].Draw(target);
        };
};// Body Class

} //namespace sf

【问题讨论】:

  • +1 有趣。但是在函数体之后不需要;
  • 如果您在源代码中添加明确的注释会很好,这样我们就可以知道这些错误报告在哪些行...开始时数数或搜索或剪切粘贴跳转很痛苦调查你的问题。干杯。
  • 是的,我从“Sam's C++”中养成了这个习惯
  • 只是一个猜测,但是头文件&lt;SFML/Graphics.hpp&gt; 是否在sf 命名空间中定义了一个名为Body 的(非模板)类?
  • @Griffin - 实际上,我的意思是说“// LINE 70 - ERROR HERE”...

标签: c++ class templates namespaces compiler-errors


【解决方案1】:

好的,找到问题了:

在之前包含的头文件中:Shape.hpp 我使用以下语法声明Body 为朋友:

friend class Body;

这显然使编译器假定 Body 不是模板(没有模板指示) 正确的语法是:

template <typename drawable>    
friend class Body;

因为现在编译器将 Body 理解为模板类

【讨论】:

  • 虽然这个答案是正确的,但您应该接受其他答案之一。即使您不明白他们的意思并一直抱怨不可能是问题,他们也会告诉您完全相同的事情。
  • 猜我不明白这是一个类的实际声明,而不仅仅是一个朋友声明,谢谢你的帮助!
【解决方案2】:

sf::Body 是一个似乎已经被使用的名称(对于一个类,而你正在声明一个模板)。您确定要将代码放在sf 命名空间中吗?使用自己的命名空间而不是他们使用的库的命名空间更为习惯。

【讨论】:

  • 该代码在过去 3 周内不是模板类时运行良好,具有相同的 sf::Body 类名。所以我不认为这是一个双重声明问题......
  • @Griffin: typedef int X; typedef int X; 是完全有效的 C++,然后您将其更改为 typedef int X; typedef double X; 并出现错误。论点:它在不同时起作用在这里不成立:这是因为它现在不同了,所以双重声明触发了错误。
【解决方案3】:

根据您的信息,最有可能的两个候选者是 Graphics.hpp{ } 不匹配,或者您的前向声明 class Body 没有将其标记为模板。

【讨论】:

  • @Griffin:如果它过去不是模板,那肯定是支持“class Body 的前向声明而不将其标记为模板”的论据。
  • 我发现了问题:我声明 Body 是前一个类的朋友,但没有将它指定为模板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-09
  • 2019-03-23
相关资源
最近更新 更多