繁体   English   中英

为什么在使用模板 function 时出现编译错误

[英]Why do i get compile error while using template function

我有一个基地 class。

#include <string.h>
class Channel
{
private:
    std::string stdstrName;

public:
    Channel() : stdstrName("CHANNEL"){   }
    Channel(std::string name) : stdstrName(name){ }
    void PrintName() { std::cout << stdstrName << std::endl; }  
};

由 Position class 继承。

class PositionChannel : public Channel
{
public:
    std::vector<int> keyframes;
    PositionChannel() : Channel("POSITION") , keyframes( { 1 , 2, 3 }) {    }
};

有一个控制器 class,它的数据成员是通道类。

#include "Channel.h"
#include <memory>

class Director
{
private:
    std::vector<std::shared_ptr<Channel>> channels;

public:
    void AddChannel(std::shared_ptr<Channel> chn) { channels.push_back(chn); }
    void GetChannel(Channel **chn) { *chn = channels[0].get(); }   
};

现在主要是 function。

 // Free function
 template<typename T>
    void GetChannel(Director *dir)
    {
        T *chn;
        dir->GetChannel(&chn);
    }

    Director dir;
    PositionChannel channel;
    std::shared_ptr<Channel> channelPointer = std::make_shared<Channel>(channel);
    dir.AddChannel(channelPointer);
    GetChannel< PositionChannel>(&dir); // here i get error  

这是错误消息 error C2664: 'cannot convert argument 1 from 'T **' to 'Channel **

如果我将模板化的 function 更改为非模板化的 function,我不会收到任何错误。

在您的GetChannel调用中, &chn参数的类型为PositionChannel** ,但Director::GetChannel参数的类型为Channel** 这两种类型不可转换 参见,例如这个问题: Conversion of pointer-to-pointer between derived and bases classes? .

我不确定你的意图是什么,因为代码没有多大意义,但你可以重新定义GetChannel如下:

template<typename T>
void GetChannel(Director *dir)
{
  Channel* ptr;
  dir->GetChannel(&ptr);
  T *chn = ptr;
}

T可以是任何类型,你不能将它转换为任何类型的Channel

可能有一些方法可以让它与模板一起工作,但我觉得你的问题可以通过使用类似这样的多态性来更容易地解决:

void GetChannel(Channel* chn, Director *dir)
{
    dir->GetChannel(&chn);
}

然后chn可以是从Channel派生的任何类型。

是的,Daniel Langr 已经给出了正确的答案。 如果派生 class,我在模板中添加了一个检查。

#include <type_traits>
class Channel
{ 
    public:
    virtual ~Channel() = default;
};

class PositionChannel : public Channel
{ 
};

struct Director{
    void GetChannel(Channel **c) {}
};
 
template <typename T,
typename = typename std::enable_if<std::is_base_of<Channel, T>::value, T>::type>
void GetChannel(Director *dir)
{
    Channel *chn;
    dir->GetChannel(&chn);
    T* ptr = static_cast<T*>(chn);
}

int main(void) {
    Director dir;
    GetChannel<PositionChannel>(&dir);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM