簡體   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