前向声明一个带有派生类模板参数的函数

问题描述

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

Error   LNK2019 unresolved external symbol 
"void __cdecl setSymetric<class Stars>(class std::vector<class Stars,class std::allocator<class Stars> > &,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 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);

解决方法

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

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