嵌套类模板专业化问题

时间:2019-01-21 13:37:16

标签: c++ templates

我有一个枚举类型,它描述了解析某些对象的方法。例如。我可以将“ len100”解析为字符串或枚举。嵌套struct Native使用一个模板参数,该参数描述了将在其中包含值的变量类型。例如。可以将“ len100”保存为字符串或uint。但是这段代码给了我一个错误:

"invalid use of incomplete type 'struct Evaluator<(Type)3>::Native<T>'"

在此行:

T Evaluator<Type::jarray>::Native<T>::eval() {

向量专门化也会发生这种情况。我该如何解决此问题,有更好的解决方案来处理此任务吗?

enum class Type
{
      juint
    , jstring
    , jenum
    , jarray
};

template<Type type>
struct Evaluator
{
    template<typename T>
    struct Native {
        static T eval();
    };
};

template<>
template<typename T>
T Evaluator<Type::jarray>::Native<T>::eval() {
    cout << "primitive" << endl;
    return T{};
}

template<>
template<typename T>
T Evaluator<Type::jarray>::Native<vector<T>>::eval() {
    cout << "vector" << endl;
    return T{};
}

int main() {
    Evaluator<Type::jarray>::Native<vector<int>>::eval();
}

1 个答案:

答案 0 :(得分:4)

对于第一种情况,您尝试提供专业化的非专业化模板成员的成员专业化。

这是禁止的。从封装类到它的成员,专门化的行为必须是下降的。首先,您要为其成员模板之一专门化封装类或专门化封装类。然后,您可以专门化此成员模板,依此类推。

第二个错误是因为您尝试为成员eval提供未声明的部分专业化Native<vector<int>>的专业化。

因此,要解决您的问题,唯一的选择是将整个模板类Native进行专业化Evaluator<Type::Jarray>。然后,您还必须为先前定义的成员模板Native定义部分专业化(它本身就是成员专业化……ouch!):

#include <iostream>
#include <vector>

enum class Type
{
      juint
    , jstring
    , jenum
    , jarray
};

template<Type type>
struct Evaluator
{
    template<typename T>
    struct Native {
        static T eval();
    };
};

//here we provide a member specialization for Evaluator
//the struct Evaluator is not entirely specialized
//it is specialized for only one of its member.
//and this member is an template
template<>
template<typename T>
struct Evaluator<Type::jarray>::Native{
    static T eval(){
      std::cout << "primitive" << std::endl;
      return T{};
      }
};

//Here we declare a partial specialization of the
//member `Native` of `Evaluator` specialized just above.
template<>
template<typename T>
struct Evaluator<Type::jarray>::Native<std::vector<T>>{
    static T eval() {
      std::cout << "vector" << std::endl;
      return T{};
     }
  };


int main() {
    Evaluator<Type::jarray>::Native<std::vector<int>>::eval();
    Evaluator<Type::jarray>::Native<int>::eval();
}