c++ - CRTP如何使派生类具有基类的容器
问题描述
我想使用 CRTP 模仿以下行为:
#include <vector>
#include <memory>
class GameNumber {
public:
~GameNumber(){}
};
class GameNumber_real : public GameNumber {
public:
GameNumber_real (float m) {n = m;}
~GameNumber_real(){}
private:
float n;
};
class GameNumber_sets : public GameNumber {
public:
GameNumber_sets (float n, float m) {
left.push_back (std::make_shared<GameNumber_real>
(GameNumber_real(n)));
right.push_back (std::make_shared<GameNumber_real>
(GameNumber_real(m)));
}
~GameNumber_sets(){}
private:
std::vector <std::shared_ptr<GameNumber>> left;
std::vector <std::shared_ptr<GameNumber>> right;
};
我的尝试是:
template <class T>
class GameNumber {}
class GameNumber_real : public GameNumber<GameNumber_real> {
public:
GameNumber_real (float m) {n = m;}
private:
float n;
};
class GameNumber_sets : public GameNumber<GameNumber_sets> {
public:
GameNumber_sets (float n, float m) {
left.push_back (std::make_shared<GameNumber_real>
(GameNumber_real(n)));
right.push_back (std::make_shared<GameNumber_real>
(GameNumber_real(m)));
}
private:
std::vector <std::shared_ptr<GameNumber>> left;
std::vector <std::shared_ptr<GameNumber>> right;
};
编译器错误是:
include/game_number.hpp:44:33: error: no matching function for call to
‘std::vector<std::shared_ptr<GameNumber<GameNumber_sets>>>
::push_back(std::shared_ptr<GameNumber_real>)’
(GameNumber_real(n)));
从消息中我了解到,在 GameNumber_sets 中,GameNumber 解析为 GameNumber_GameNumber_sets_。如果您能告诉我如何实现我所期望的行为,我将非常高兴。
解决方案
您可以显式指定模板参数GameNumber<GameNumber_real>
,它将解决您的问题。
您也可以将构造函数参数直接传递给std::make_shared
.
改进的代码:
template <class T>
class GameNumber {};
class GameNumber_real : public GameNumber<GameNumber_real> {
public:
GameNumber_real (float m) {n = m;}
private:
float n;
};
class GameNumber_sets : public GameNumber<GameNumber_sets> {
public:
GameNumber_sets (float n, float m) {
left.push_back (std::make_shared<GameNumber_real>(n));
right.push_back (std::make_shared<GameNumber_real>(m));
}
private:
std::vector <std::shared_ptr<GameNumber<GameNumber_real>>> left;
std::vector <std::shared_ptr<GameNumber<GameNumber_real>>> right;
};
但是我不明白为什么在这里需要 CRTP,在您的示例中没有使用它。
编辑:
据我所知,您不能使用 CRTP 作为接口。但是,如果 c++17 适合您,那么有std::any
(https://en.cppreference.com/w/cpp/utility/any )可能会有所帮助。
代码如下所示:
template <class T>
class GameNumber {};
class GameNumber_real : public GameNumber<GameNumber_real> {
public:
GameNumber_real (float m) {n = m;}
private:
float n;
};
class GameNumber_sets : public GameNumber<GameNumber_sets> {
public:
GameNumber_sets (float n, float m) {
left.push_back (std::make_shared<std::any>
(GameNumber_real(n)));
right.push_back (std::make_shared<std::any>
(GameNumber_real(m)));
}
private:
std::vector <std::shared_ptr<std::any>> left;
std::vector <std::shared_ptr<std::any>> right;
};
推荐阅读
- c - 如何修改日期验证程序以接受键盘输入作为“一个字符串”?
- html - 为什么 gmail 不响应媒体查询?
- java - 如何修改附加到多个 JButton 的动作侦听器的参数?
- websocket - Spring Websocket连接因保留位无效而自动关闭
- python-3.x - 即使我为它分配值,也没有使用局部变量'result'值,任何人都可以告诉为什么'result'未使用
- reactjs - 如何从组件中获取值并将其控制台记录在提交上?(反应)
- python-3.x - 通过传递多个变量(数字和字符串)创建新变量
- hadoop - 如何在hadoop中构建代码目录
- c# - 试图从文本文件读入列表
- laravel - 无法访问 IBM Tone Analyzer API?