【发布时间】:2018-08-08 08:00:25
【问题描述】:
我最近开始研究模板元编程,只是意识到模板调试有多么困难。例如,当我尝试编译以下代码时收到“指向引用的指针非法”错误:
#include <vector>
#include <tuple>
//Empty Entity Class
class Entity {
};
#define COMPONENTS X(Entity)
#define COMPONENTSLIST X(Entity)
#define X(ARG) std::vector<ARG>
using ComponentTuple = std::tuple<COMPONENTSLIST>;
#undef X
//EntityManager stuff
class EntityManager {
static ComponentTuple components;
public:
template<class T>
static auto& Components();
template<class T>
static void AddComponent(Entity&, T&&);
};
template<class T>
auto& EntityManager::Components()
{
return std::get<std::vector<T>>(components);
}
template<class T>
void EntityManager::AddComponent(Entity& e, T&& c) {
auto& comp = Components<T>();;
comp.push_back(c);
}
#define X(ARG) std::vector<ARG>
std::tuple<COMPONENTSLIST> EntityManager::components;
#undef X
//ContentManager Stuff
class ContentManager {
bool LoadComponent(std::string data, Entity& entity);
template <class T>
static void LoadComponent(std::string data, Entity& entity);
};
template <class T>
void ContentManager::LoadComponent(std::string data, Entity& entity) {
T component{};
EntityManager::AddComponent(entity, component);
}
bool ContentManager::LoadComponent(std::string data, Entity& entity) {
LoadComponent<Entity>(data, entity);
}
错误的原因是LoadComponent 中的EntityManager::AddComponent(entity, component); 行(考虑到xmemory 的错误点不容易弄清楚)。
我遇到的问题是,据我所知,我从未请求过指针,所以这个错误对我来说似乎很奇怪。
在这一点上,任何帮助将不胜感激(关于错误甚至未来模板调试的提示)。提前致谢。
【问题讨论】:
-
麻烦解析
T component();(函数解密),改用T component{};。 -
@Jarod42 有什么区别?它不等同于同一件事,还是只是一个标准?不是在调用构造函数吗?
-
如前所述:
T component()声明了一个名为component的函数,没有参数并返回一个T,而T component{}创建一个名为T的类型为component的对象。跨度> -
@Ryoku 你搜索过“Vexing parse”吗?你会发现整个 wiki 页面比这里的评论更能描述它
-
auto& comp = Components<T>();有问题:引用或临时变量。另请注意,在您的情况下,Components<T>()将是Components<U&>()(因为T&&来自左值)您可能想要std::decay_t<T>。
标签: c++ templates reference c++14 pass-by-reference