c++ - 如何让内部模板类成为外部模板类的类型?

标签 c++ class templates inheritance nested

我当前的代码如下所示:Code here

我有一个模板 ClassOuter 和一个嵌套模板 ClassInnerBase,其中 TypeD 可以是任何类型的 TypeA,TypeB, TypeC 而不是其他。此外,ClassInnerDerived 应继承自 ClassInnerBase 并实现 virtual const int Method(int id) = 0;

template<typename TypeA, typename TypeB, typename TypeC>
class ClassOuter {
public:

    class ClassInnerBase {
    public:
        ClassInnerBase(int x) :
                m_x(x) {
        }

        virtual const int Method(int id) = 0;

    private:
        int m_x;
    };

    template<typename TypeD>
    class ClassInnerDerived : public ClassInnerBase {
    public:
        ClassInnerDerived<TypeD>(const TypeD &object, int x) :
                ClassInnerBase(x), m_object(object) {

        }

        // Implementation of ClassInnerBase::Method for type float
        template<>
        const int ClassInnerDerived<float>::Method(int id){
            return GetLookupID(id);
        }

        // Implementation of ClassInnerBase::Method for type double
        template<>
        const int ClassInnerDerived<double>::Method(int id){
            return GetLookupID(id);
        }


    private:
        TypeD m_object;
    };

    void DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id);

    const int GetLookupID(int id) const{
        return lookup[id];
    }

private:
    int lookup[100];
};

template<typename TypeA, typename TypeB, typename TypeC>
void ClassOuter<TypeA, TypeB, TypeC>::DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id){
    for(const auto &inner : inner_vec){
        inner.Method(id);
    }
}


int main()
{
    std::vector<typename ClassOuter<int, double, float>::ClassInnerBase> class_base_objects;
    typename ClassOuter<int, double, float>::template ClassInnerDerived<float> class_inner_derived_object(0.2f, 1);
    class_base_objects.push_back(class_inner_derived_object);

    typename ClassOuter<int, double, float>::template DoSomething(class_base_objects, 1);
}

我最终得到了错误:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp:30:18: error: explicit specialization in non-namespace scope 'class ClassOuter<TypeA, TypeB, TypeC>::ClassInnerDerived<TypeD>'
         template<>
                  ^

我被困在这里,不知道如何解决这个错误。 另外,对于 ifself 的实现有什么建议/意见/改进吗?

最佳答案

正如您的编译器所说,您不能显式(完全)专门化模板类的内部类。你正在做的事情更糟,因为你试图从内部类中专门化一个方法,即使对于非嵌套模板类也是不可能的......你可以做的是通过添加具有默认值的额外模板参数来欺骗编译器到你的内部类并部分地专门化整个内部类。这实际上会让您使用 sfinae 机制测试模板参数是否属于给定类型(我在您的示例中测试了内部模板参数是否字面上是 double 或 float ,但您可以类似地测试它是否是外部模板类型之一以及)例如:

#include <iostream>
#include <type_traits>
#include <vector>

template<typename TypeA, typename TypeB, typename TypeC>
class ClassOuter {
public:

    class ClassInnerBase {
    public:
        ClassInnerBase(int x) :
                m_x(x) {
        }

        virtual const int Method(int id) = 0;

    private:
        int m_x;
    };

    template<typename TypeD, typename = void>
    class ClassInnerDerived;

    template<typename TypeD>
    class ClassInnerDerived<TypeD, std::enable_if_t<std::is_same<TypeD, float>::value || std::is_same<TypeD, double>::value> >: public ClassInnerBase {
    public:
        // Implementation of ClassInnerBase::Method for type float
        ClassInnerDerived(const TypeD &object, int x) :
                ClassInnerBase(x), m_object(object) {
        }
        const int Method(int id){
            return GetLookupID(id);
        }
    private:
        TypeD m_object;
    };

    public:

    //static void DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id);

    static const int GetLookupID(int id) {
        return lookup[id];
    }

private:
    static int lookup[100];
};

template<typename TypeA, typename TypeB, typename TypeC>
int ClassOuter<TypeA, TypeB, TypeC>::lookup[100];

/*
template<typename TypeA, typename TypeB, typename TypeC>
void ClassOuter<TypeA, TypeB, TypeC>::DoSomething(const std::vector<ClassInnerBase> &inner_vec, int id){
    for(const auto &inner : inner_vec){
        inner.Method(id);
    }
}*/


int main()
{
std::vector<typename ClassOuter<int, double, float>::ClassInnerBase *> class_base_objects;
    //typename ClassOuter<int, double, float>::template ClassInnerDerived<float> class_inner_derived_object(0.2f, 1);
    class_base_objects.push_back(new ClassOuter<int, double, float>::ClassInnerDerived<float>(0.2f, 1)); //(class_inner_derived_object);

    //typename ClassOuter<int, double, float>::template DoSomething(class_base_objects, 1);
}

上面的代码可能并没有真正做你想做的,但我认为这是一个很好的起点......

关于c++ - 如何让内部模板类成为外部模板类的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37944457/

相关文章:

javascript - 无法对使用类选择器检索到的元素执行任何操作

templates - 在 Twig 的父作用域中设置变量

c++ - 函数模板中的参数推导

c++ - 读取文件以构造具有多种成员类型

c++ - C++ 对象数组上的 OpenMP for 循环

java - 在类中使用静态方法时没有输出(其中没有 main 函数的类)

c++ - 类型在 SFINAE 中未继承以进行多重继承?

C++ 将字符串转换为其 ASCII 表示形式

c++ - 将对基类的引用传递给 boost::thread,并调用派生类中的虚函数是否可行?

objective-c - copyWithZone 被调用