我类的一个成员方法以枚举类型作为参数:它对不同的枚举产生不同的副作用。我想知道是否可以将模板用作查找表,我想到了两种可能的解决方案,但似乎都不起作用:
//// 1 ////
class A {
public:
enum AEnum : uint8_t { first, second, ... };
private:
template<AEnum N, typename T>
struct impl {
static void do_sth(T t) { ... };
};
template<typename T>
struct impl<first, T> {
static void do_sth(T t) { ... };
};
public:
template<typename T>
void do_sth(AEnum e, T t) {
impl<e, T>::do_sth(t);
}
}
//// 2 ////
class A {
public:
enum AEnum : uint8_t { first, second, ... };
private:
template<typename T_enum, typename T>
struct impl {
static void do_sth(T t) { ... };
};
template<typename T>
struct impl<uint8_t[2], T> { // A::first
static void do_sth(T t) { ... };
};
public:
template<typename T>
void do_sth(AEnum e, T t) {
impl<uint8_t[static_cast<uint8_t>(e) + 1u], T>::do_sth(t);
}
}
以这种方式编码真的是个坏主意吗?
@奥利查尔斯沃思
What's wrong with a switch statement?
do_sth 的第二个参数 (T) 支持的类型随 e 的值而变化,例如A::first 支持积分,A::second STL 容器,例如:
template<typename T>
void do_sth(AEnum e, T t) {
switch(e) {
case first:
std::cout << &t << std::endl;
break;
case second:
std::cout << t.data() << std::endl;
break;
default:
break;
}
A a;
a.do_sth(A::first, 0);
最佳答案
您必须使 AEnum arg 成为 do_sth 的模板参数:
template<AEnum e, typename T>
void do_sth(T t) { ... }
...并将其命名为 a.do_sth<A::first>(0)
.
或者,您可以编写单独的函数(do_sth_integral
、do_sth_container
、...),或者,如果对于特定 T 只有一个正确的操作过程,则推导出给定的“正确”枚举值T 使用元编程/重载技巧。
例如,这是一种编写两个函数的方法,例如检测数字类型和容器类型:
//The extra dummy argument is invalid for types without a nested
//"iterator" typedef
template<typename T>
void do_sth(T t, typename T::iterator * = 0)
{
//container type code
}
//The dummy arg is invalid for types without a
//std::numeric_limits specialization
template<typename T>
void do_sth(T t,
typename boost::enable_if_c<std::numeric_limits<T>::is_specialized>::type * = 0)
{
//numeric type code
}
当然,如果您传递的 T 具有迭代器 typedef 和 numeric_limits 特化,或者两者都没有,这将失败。
如果对于特定的 T 只有一个合理的操作,并且很难正确猜测应该对未知的 T 使用哪个重载,那么您可以使用用户必须明确专门化的特征类,或者只要求用户专门化“impl”或调度类。
你不能写一个函数来做类似 3.data()
的事情,即使程序运行时从未调用该代码路径。编译器不知道它永远不会被调用,并且在任何情况下,它都会以导致诊断错误所需的方式违反语言的类型系统。
关于c++ - 使用可变修改类型实例化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3639476/