Reputation: 191
I have a enum Type that describes methods of parsing some objects. E.g. I can parse "len100" as a string either a enumeration. Nested struct Native takes a template argument that describes a type of the variable in which value will be contained. E.g. "len100" can be saved to string or uint. But this code gives me an error:
"invalid use of incomplete type 'struct Evaluator<(Type)3>::Native<T>'"
on this line:
T Evaluator<Type::jarray>::Native<T>::eval() {
This happens also with the vector specialization. How can I fix this problem and is there a better solution to handle this task?
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();
}
Upvotes: 2
Views: 105
Reputation: 18051
For the first case you try to provide a member specialization of an unspecialized template member of a specialization.
This is forbidden. The act of specializing must be descending, from the encapsulating class toward its member. First you specialize the encapsulating class or specialize the encapsulating class for one of its member template. Then you can specialize this member template, and so on.
The second error is because you try to provide a specialization of the member eval
for an undeclared partial specialization Native<vector<int>>
.
So to fix your issue, the only option is to specialize the entire template class Native
for the specialization Evaluator<Type::Jarray>
. Then you must also define a partial specialization for the previously defined member template Native
(itself is a member specialization ... 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();
}
Upvotes: 4