我想创建一个以参数为参数的模板函数,而不是模板类型本身,而是模板类型的成员枚举类。这可能吗?
以下代码演示了我想要实现的目标,我想知道是否有一些模板魔术可以为我完成目标。
#include <iostream>
using namespace std;
class A{
public:
enum class ID {a1, a2};
static void f(ID id){
switch(id){
case ID::a1:
std::cout << "a1\n";
break;
case ID::a2:
std::cout << "a2\n";
break;
}
}
};
class B{
public:
enum class ID {b1};
static void f(ID id){
switch(id){
case ID::b1:
std::cout << "b1\n";
break;
}
}
};
template<typename TypeName>
void g(TypeName::ID id){
TypeName::f(id);
}
int main(int argc, char **argv){
g(A::ID::a1);
g(A::ID::a2);
g(B::ID::b1);
return 0;
}
所需的输出为
a1
a2
b1
尤其要注意我如何让函数g以TypeName :: ID作为参数而不是TypeName。
首选C ++ 11解决方案,但也需要使用更高版本的解决方案。
答案 0 :(得分:3)
#include <iostream>
using namespace std;
class A{
public:
enum class ID {a1, a2};
static void f(ID id){
switch(id){
case ID::a1:
std::cout << "a1\n";
break;
case ID::a2:
std::cout << "a2\n";
break;
}
}
};
class B{
public:
enum class ID {b1};
static void f(ID id){
switch(id){
case ID::b1:
std::cout << "b1\n";
break;
}
}
};
template<typename TypeName>
void g(typename TypeName::ID id){
TypeName::f(id);
}
int main(int argc, char **argv){
g<A>(A::ID::a1);
g<A>(A::ID::a2);
g<B>(B::ID::b1);
return 0;
}
答案 1 :(得分:2)
template<typename TypeName>
void g(TypeName::ID id){ // WRONG
TypeName::f(id);
}
需要typename
:
template<typename TypeName>
void g(typename TypeName::ID id){
TypeName::f(id);
}
但是,类型是不可推论的(由于::
)。
因此在呼叫站点,您必须指定类型:
g<A>(A::ID::a1);
g<A>(A::ID::a2);
g<B>(B::ID::b1);
或者,为了保持预期的呼叫站点语法,您可以创建特征以将(枚举)类型绑定到类:
template <typename E> struct ClassFromId;
template <> struct ClassFromId<A::ID> { using type = A; };
template <> struct ClassFromId<B::ID> { using type = B; };
template<typename E>
void g(E id){
ClassFromId<E>::type::f(id);
}