gpt4 book ai didi

C++模板问题

转载 作者:行者123 更新时间:2023-11-30 02:29:09 24 4
gpt4 key购买 nike

对于(无论如何对于我的水平而言)相当复杂的模板问题,我将不胜感激。

让我先解释一下我的“系统”。

模拟一个基本的音频混合和流媒体系统,它包含三个构建组件:

BufferPlayer 将从中处理数据。由于它们直接由数据连接,因此它们的数据需要属于同一类型。因此 Buffer<T> ~ Player<T> ,这里的模板必须匹配。

这些都包裹在 Manager 中,他最终会将所有传入的缓冲区管理到一个播放器中。

现在,缓冲区和播放器都需要一些不同的实现,因此它们由通用接口(interface)表示为 iPlayer 和 iBuffer。

我的目标是能够像这样声明一个管理器:

simple_manager<simple_player<float>>;

或至少失败

simple_manager<simple_player , float>;

因为我不确定第一个是否有解决方案,所以我对第二个的尝试是这样的:

template <typename K>
class iManager {
private:
K player;
};

template <template <typename> class C , typename T>
class simple_manager : iManager< C<T> > {
public:
void play(iBuffer<T> & _buffer,const audio_descriptor ad, bool * condition){
player.play(_buffer,ad,condition);
}


};

如您所见,在具体类中,T 标记要操作的数据类型,而 C 是我希望使用的播放器的具体类。该接口(interface)只有一个模板,再次标记具体的播放器类。所以K ~ C<T>

这不会编译(仅)出现以下错误:

simple_manager.cpp: In member function ‘void simple_manager<C, T>::play(iBuffer<T>&, audio_descriptor, bool*)’:
simple_manager.cpp:18:12: error: ‘player’ was not declared in this scope
player.play(_buffer,ad,condition);
^~~~~~

我不知道是什么原因造成的。编译器不能推断出 T 必须继承自 iPlayer,因为 iPlayer 必须实现一个 play() 方法。

如果我这样定义 simple_manager,我可以让它真正工作:

class simple_manager : iManager< simple_player<float> > {...}

但它仍然无法工作:

class simple_manager : iManager< simple_player<T> > {...}

我被难住了。如果我有 <T extends iPlayer>在 Java 中,这会起作用,但我猜想编译时模板化是一个更难的问题。

如有任何帮助,我们将不胜感激!

最佳答案

第一个问题是 player无法从派生类访问,因为它被标记为 private而不是 protected .你可以做到 protected或添加一些 protected访问它的成员函数:

template <typename K>
class iManager {
protected:
K player;
};

但是,这仍然行不通,因为 iManager<C<T>>是一个依赖基类,因此它的成员在不合格的名称查找中是隐藏的。要解决此问题,您可以通过 this 访问它。指针:

void play(iBuffer<T> & _buffer,const audio_descriptor ad, bool * condition){
this->player.play(_buffer,ad,condition);
}

为了在您的第一个示例中获得良好的用法,您可以编写一个特征来从给定类型中提取模板参数:

template <typename T> struct extract_inner;

template <template <typename> class C, typename T>
struct extract_inner<C<T>> { using type = T; };

template <typename T>
using extract_inner_t = typename extract_inner<T>::type;

然后可以用来为 iBuffer 提供正确的参数:

template <typename T>
class simple_manager : iManager< T > {
public:
void play(iBuffer<extract_inner_t<T>> & _buffer,
const audio_descriptor ad, bool * condition){
this->player.play(_buffer,ad,condition);
}
};

Live demo

关于C++模板问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39876363/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com