c++ - builder 模式、模板和嵌套类

标签 c++ templates nested

我正在尝试用 C++ 开发一个嵌套的构建器类,但我一直收到“无效使用不完整类型 'class Np​​c::Builder<'T>”的错误。我搜索了很多,但找不到答案。有谁能帮帮我吗?

这是我的代码:

Npc.h
class Npc{
     ...
    template<class T, class enable_if<is_base_of<Npc, T>::value>::type* = nullptr>
    class Builder{

    private:
        T* instance;

    public:
        Npc::Builder<T>* create();
        Npc::Builder<T>* name(string name);
        Npc::Builder<T>* charClass(string charClass);
        Npc::Builder<T>* hp(int hp);
        Npc::Builder<T>* mana(int mana);
        Npc::Builder<T>* attackPower(int attackPower);
        Npc::Builder<T>* magicPower(int magicPower);
        Npc::Builder<T>* defense(int defense);
        Npc::Builder<T>* magicDefense(int magicDefense);
        T* build();
    };
};


Npc.cpp
...
template<class T, class enable_if<is_base_of<Npc, T>::value>::type* = nullptr>
Npc::Builder<T>* Npc::Builder<T>::create() {
   ...
}

main.cpp
...
Npc::Builder<Warrior>* builder = new Npc::Builder<Warrior>();
...

谢谢!

最佳答案

您的代码中存在一些语法错误。最重要的是,你是missing a typename (as you have a dependent type) ,并且第二个模板参数在这种情况下是非类型的,因为您将其默认为 nullptr。使用

// non-type param
template<class T, typename std::enable_if<std::is_base_of<Npc, T>::value>::type* = nullptr> 
class Builder { ... };

或者,让它成为一个类型

// type param
template<class T, class = typename std::enable_if<std::is_base_of<Npc, T>::value>::type> 
class Builder { ... };

接下来,行

template<class T, enable_if<is_base_of<Npc, T>::value>::type* = nullptr>
Npc::Builder<T>* Npc::Builder<T>::create() {
   ...
}

不正确:缺少 typename,不能有默认参数。在定义中,编译器也认为您部分特化了模板成员函数,这是不允许的。你需要的是这样的:

template<class T, typename std::enable_if<std::is_base_of<Npc, T>::value>::type* U>
Npc::Builder<T, U>* 
Npc::Builder<T, U>::create() {
    return nullptr;
}

下面的代码显示了一个完整的工作示例,它修复了上述所有问题:

#include <iostream>
#include <type_traits>

class Npc {
public: 
    template<class T, 
             typename std::enable_if<std::is_base_of<Npc, T>::value>::type* U = nullptr>
    class Builder {
    private:
        T* instance;    
    public:
        Builder* create(); // no need for Noc::Builder<T>, due to template name injection
        Builder* name(std::string name);
        Builder* charClass(std::string charClass);
        Builder* hp(int hp);
        Builder* mana(int mana);
        Builder* attackPower(int attackPower);
        Builder* magicPower(int magicPower);
        Builder* defense(int defense);
        Builder* magicDefense(int magicDefense);
        T* build();
    };
};

struct Warrior: Npc{};

template<class T, typename std::enable_if<std::is_base_of<Npc, T>::value>::type* U>
Npc::Builder<T, U>* 
Npc::Builder<T, U>::create() {
    return nullptr;
}

int main()
{
    Npc::Builder<Warrior>* builder = new Npc::Builder<Warrior>();
    delete builder;
}

Live on Coliru

关于c++ - builder 模式、模板和嵌套类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38023567/

相关文章:

C++11 和 Visual Studio - 未解析的外部符号

node.js - 如何在 mongoose 中使用嵌套模式(使用 'type' )来创建数组?

c++ - 类中的枚举,具有显式作用域,C++11 之前的版本?

c++ - 这种编译时确定继承的模式有名字吗?

具有 const 限定符的自由函数类型的 C++ 特化

c++ - 隐式类实例化翻译单元 : multiple definition when linking

c++ - 类模板的友元函数的显式特化

css - 文本溢出省略号不适用于动态宽度

python - 如何制作嵌套字典并动态追加数据

c++ - 替代函数语法差异