【问题标题】:Forward declare a function with template parameter of derived class前向声明带有派生类模板参数的函数
【发布时间】:2021-05-28 23:25:55
【问题描述】:

我一直在尝试转发声明一个接受模板参数的函数,但是在传递派生类对象时它给了我

Error   LNK2019 unresolved external symbol 
"void __cdecl setSymetric<class Stars>(class std::vector<class Stars,class std::allocator<class Stars> > &,int,int,float,float)"
 (??$setSymetric@VStars@@@@YAXAEAV?$vector@VStars@@V?$allocator@VStars@@@std@@@std@@HHMM@Z) referenced in function 
"public: __cdecl Sector::Sector(class sf::RenderWindow &,class std::vector<class Window *,class std::allocator<class Window *> >,
class std::vector<class Image,class std::allocator<class Image> > const &)"
 (??0Sector@@QEAA@AEAVRenderWindow@sf@@V?$vector@PEAVWindow@@V?$allocator@PEAVWindow@@@std@@@std@@AEBV?$vector@VImage@@V?$allocator@VImage@@@std@@@4@@Z)        

但是当我使用基类更改参数时,它工作正常。

这是我在 main.cpp 中的函数实现:

template<typename A>
void setSymetric(std::vector<A>& buttons, const int startWidth,
    const int width, const float x, const float y)
{
    float substractedWidth = width - startWidth - (x * buttons.size());
    float deltaWidth = substractedWidth / (buttons.size() * 2);

    float currPos = startWidth;

    for (auto& k : buttons)
    {
        currPos += deltaWidth;

        k.getShape().setPosition(currPos, y);
        currPos += x + deltaWidth;
    }

}

这是我在我使用它的其他文件中转发声明它的方式(Sector.h 它是一个内联标头(我将我的实现和声明放在那里,但我会将它们分开)

template<typename A>
extern void setSymetric(std::vector<A>& buttons, const int startWidth, const int width,
    const float x, const float y);

我的基类:

#ifndef IMAGES
#define IMAGES

#include<string>
#include<iostream>

#include <SFML/Audio.hpp>
#include <SFML/Graphics.hpp>

const std::string ImagePath = "Content/";
const std::string AudioPath = "Sound/";

extern const double width;
extern const double height;

class Image
{
public:

    Image()
    {

    }
    void play()
    {
        this->player.play();
    }

    void setTexture(const std::string& texture)
    {
        if (!this->texture.loadFromFile(ImagePath + texture))
            std::cout << "problem \n";
        shape.setTexture(&this->texture);
        shape.setSize(sf::Vector2f((width + height) / 19, (width + height) / 19));
    }

    void setTexture(const sf::Texture& texture)
    {
        this->texture = texture;
    }

    sf::Texture& getTexture()
    {
        return this->texture;
    }

    void setSound(const std::string& sound)
    {
        this->sound.loadFromFile(AudioPath + sound);
        player.setBuffer(this->sound);
    }

    sf::RectangleShape& getShape()
    {
        return this->shape;
    }

    void setVisibility(const bool flag)
    {
        this->isVisible = flag;
        if (flag == false)
        {
            this->size = this->shape.getSize();
            shape.setSize(sf::Vector2f(0, 0));
        }
        else
            shape.setSize(this->size);
    }

protected:
    sf::Texture texture;
    sf::RectangleShape shape;

    bool isVisible = true;
    sf::Vector2f size;

    sf::SoundBuffer sound;
    sf::Sound player;
};

#endif

这是我要传递的派生类:

#pragma once

#include "Images.h"

class Stars : public Image
{
public:
    Stars() : Image() {

    }

    void activate() {
        this->setTexture("star.png");
    }
};

stars 是具有 Stars 数据类型的二维数组。 (当它是图像时它正在工作) 这就是我传递它的方式:

setSymetric(stars[i], this->game[i].getShape().getPosition().x,
                this->game[i].getShape().getPosition().x + this->game[i].getShape().getSize().x,
                stars[i][0].getShape().getSize().x,
                this->game[i].getShape().getPosition().y + this->game[i].getShape().getSize().y);

【问题讨论】:

  • 注意:模板是在编译时解析的,既不是在运行时也不是在链接时。这就是模板类通常在包含文件中完全定义的原因。如果某个部分仅在源 .c 文件中定义,则无法生成所有模板版本,并且您会收到链接错误。

标签: c++ templates inheritance forward-declaration


【解决方案1】:

您必须在某处显式实例化缺少的函数和构造函数。到目前为止,您只使用它们,即引用它们,但您编写的任何代码都不会导致编译器实际创建这些类型的实例并发出它们。因此出现错误。

参见例如this answer 了解更多关于显式实例化的信息。

【讨论】:

  • 对不起,我真的不明白为什么我会收到错误。你能解释一下吗?为什么我不能通过这样的派生类?它适用于 Image 对象。
猜你喜欢
  • 1970-01-01
  • 2011-11-18
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
相关资源
最近更新 更多