调用默认构造函数时模板可变参数编译错误

时间:2019-03-09 10:21:10

标签: c++ templates variadic entityx

我对调用模板可变参数方法的模板方法有一种奇怪的行为,但我找不到问题所在。我正在使用Visual Studio Community 2017。

以下方法中出现编译错误:

// AScene.hpp
#include "Scriptable.hpp"

template <typename T>
void AScene::initialize_(void) {
    std::shared_ptr<AGameObject> root = std::make_shared<T>();

    // ...
    root->addComponent<Scriptable>(3); // it works (3 is just a random value to bypass the default constructor, see below the Scriptable struct definition)
    root->addComponent<Scriptable>(); // error C2760 unexpected token ')', expected 'expression'
    // ...
}

如果我尝试在此方法中使用默认构造函数,则会遇到上述编译错误。 在派生类中调用此方法,这里:

// MyScene.cpp
#include "AScene.hpp"

void MyScene::initialize(void) {
    AScene::initialize_<Level>();
    // If I call root->addComponent<Scriptable>() directly here, its working perfectly
}

这是 addComponent 模板可变参数方法的实现:

// AGameObject.hpp
template <typename C, typename ...Args>
void AGameObject::addComponent(Args&& ... args) {
    entity_.assign<C>(std::forward<Args>(args) ...);
}

由于它是库的一部分,所以我无法向您显示assign()代码,但是当我没有在 initialize _ 中调用它时,该代码将始终有效。

这是我的可编写脚本的类:

// Scriptable.hpp
struct Scriptable {
    Scriptable(void) = default;
    Scriptable(int i) {} // remember, used to bypass the default constructor
    // ...
};

实际上,当我在模板方法 initialize _ 中调用 addComponent 方法时,似乎编译器只是忽略/找不到默认构造函数。你知道我在做什么错吗?

如果您需要更多信息,请告诉我。

编辑:

我刚刚检查了库中的 assign()实现,构造函数被这样调用:

C(std::forward<Args>(args) ...);

如果要检查链接,请点击以下链接:https://github.com/alecthomas/entityx/blob/master/entityx/Entity.h#L648

这正是编译器告诉我的内容:

1>AGameObject.cpp 1>path\ascene.hpp(89): error C2760: syntax error: unexpected token ')', expected 'expression' 1>path\ascene.hpp(89): note: This diagnostic occurred in the compiler generated function 'void AScene::initialize_(void)'

1 个答案:

答案 0 :(得分:0)

我很惊讶看到这个问题没有答案。我遇到了同样的问题,发现这可行:

    root->addComponent<Scriptable>(3); // it works (3 is just a random value to bypass the default constructor, see below the Scriptable struct definition)
    root->addComponent<Scriptable>(); // error C2760 unexpected token ')', expected 'expression'
    root->template addComponent<Scriptable>(); //it works too

PS这是我很久以前才刚刚学会做的奇怪事情之一,实际上并没有理解为什么需要这样做。此处解释了其背后的理论:Calling template function within template class 但是话又说回来,我不明白为什么带有参数编译的调用就可以了。因此,如果有人可以详细说明,我将不胜感激。