提问人:Luchian Grigore 提问时间:2/22/2014 最后编辑:Luchian Grigore 更新时间:2/22/2014 访问量:75
为具有对象或对象数组作为成员的类运行不同的代码
Run different code for a class that has either an object or an array of objects as a member
问:
我有一个将对象作为参数的方法
void fun(const Obj& obj)
Obj
可以通过两种不同的方式定义:
struct Obj
{
Type x;
};
和
struct Obj
{
Type x[42];
};
我无法修改 的定义(即我无法重命名类)。另外,我无法修改 的签名,我宁愿不在 中使用预处理器指令。有没有办法使用元编程来编译和工作,而不管包含哪个定义:Obj
fun
fun
Obj
void fun(const Obj& obj)
{
impl(obj); // executes some code if obj.x is an object
// executes some other code if obj.x is an array
}
?有没有办法在没有 C++11 功能的情况下做到这一点?
答:
2赞
jrok
2/22/2014
#1
您可以根据以下条件选择模板的专业化:decltype(obj.x)
template<typename T>
void impl(const Obj&);
template<>
void impl<Type>(const Obj&) {}
template<>
void imp<Type[42]>(const Obj&) {}
void fun(const Obj& obj)
{
impl<decltype(obj.x)>(obj);
}
可能的 C++03 方式是检查是否存在的成员检测器特征类。这一次,模板参数 这样你就可以简单地传递检查的结果:Type Obj::x
impl
bool
template<typename C>
struct has_Type_x {
template<typename U, U>
struct Check;
typedef char(&yes)[1];
typedef char(&no)[2];
template<typename> static no test(...);
template<typename U> static yes test(Check<Type U::*, &U::x>*);
static const bool value = sizeof(test<C>(0)) == sizeof(yes);
};
template<bool> void impl(const Obj&);
template<>
void impl<true>(const Obj&) {}
template<>
void impl<false>(const Obj&) {
std::cout << "arr";
}
void fun(const Obj& obj)
{
impl< has_int_x<Obj>::value >(obj);
}
评论
0赞
Luchian Grigore
2/22/2014
说我不能使用 C++11?
1赞
jrok
2/22/2014
这需要更多的打字。Brb :)
0赞
Alex Antonov
2/22/2014
#2
我的建议是使用函数重载。在你的情况下,你不需要元编程/模板:
void fun(const Obj& obj)
{
impl(obj.x);
}
void impl(const Type& x){...}
void impl(Type x[]){...}
如果声明为 ,则将调用第一个版本。同样,在另一种情况下,将调用第二个版本。Obj::x
Type x
impl()
impl()
1赞
iavr
2/22/2014
#3
这可以通过第二次调用实现函数来完成,该函数也作为参数。此函数专门用于通过两个重载的标量或数组,后者接受对数组的引用,因此也保持数组大小:fun_impl
obj.x
template <typename Obj, typename T>
void fun_impl(const Obj& obj, const T& x) {}
template <typename Obj, typename T, size_t N>
void fun_impl(const Obj& obj, const T (&x)[N]) {}
template <typename Obj>
void fun(const Obj& obj)
{
fun_impl(obj, obj.x);
}
这在 C++03 中有效,不需要任何特征特征或 SFINAE。另请参阅实时示例,为方便起见,其余部分使用 C++11。
如果仅包含 ,则可以将其作为参数从 中删除。我把它留在这里是为了更普遍的情况,那里可能还有其他成员。obj
x
fun_impl
obj
请注意,它本身在这里作为模板给出;我想这是您无论如何都需要做的,因为您正在处理 .fun
Obj
评论
0赞
Alex Antonov
2/22/2014
不幸的是,您的解决方案不符合要求,因为 OP“无法修改乐趣的签名”。
0赞
iavr
2/22/2014
@AlexAntonov 我的解决方案是指专门针对标量或数组。添加模板参数只是另一个建议。这两者是无关的。fun
上一个:如何使每帧分支优化友好?
评论
std::is_array()
静态检查的解剖结构可能是个好主意,看看它如何为 c++03 标准实现(我很确定它应该是可能的)。