C++ 为具有对象或对象数组作为成员的类运行不同的代码
我有一个以对象为参数的方法C++ 为具有对象或对象数组作为成员的类运行不同的代码,c++,templates,template-meta-programming,C++,Templates,Template Meta Programming,我有一个以对象为参数的方法 void fun(const Obj& obj) Obj可以用两种不同的方式定义: struct Obj { Type x; }; 及 我无法修改Obj的定义(即,我无法重命名类)。另外,我不能修改fun的签名,我不希望在fun中使用预处理器指令。是否有一种方法可以使用元编程来编译和工作,而不管包含了Obj的哪个定义: void fun(const Obj& obj) { impl(obj); // executes some code
void fun(const Obj& obj)
Obj
可以用两种不同的方式定义:
struct Obj
{
Type x;
};
及
我无法修改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功能,有没有办法做到这一点?您可以根据
decltype(obj.x)
选择模板的专门化:
我的建议是使用函数重载。在您的案例中,您不需要元编程/模板:
void fun(const Obj& obj)
{
impl(obj.x);
}
void impl(const Type& x){...}
void impl(Type x[]){...}
如果
Obj::x
声明为Type x
,则将调用第一个impl()
版本。类似地,在另一种情况下,将调用第二个impl()
版本。这可以通过第二次调用实现函数fun\u 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);
}
模板
void fun_impl(const Obj&Obj,const T&x){}
模板
void fun_impl(const Obj&Obj,const T&x)[N]){
模板
无效乐趣(const Obj和Obj)
{
娱乐项目(obj,obj.x);
}
这在C++03中工作,不需要任何特性或SFINAE。另请参见,为方便起见,其余部分使用C++11
如果obj
仅包含x
,则可以将其作为参数从fun\u impl
中删除。我把它放在这里是为了更一般的情况,obj
可能还有其他成员
注意,
fun
本身在这里作为模板给出;我想这是你无论如何都需要做的,因为你正在处理不同的Obj
定义,比如说我不能使用C++11?那需要更多的输入。Brb:)对不起,我已经检查了没有C++11功能限制的。无论如何,检查静态检查的结构是一个好主意,看看如何为c++03标准实现它(我很确定这应该是可能的)。不幸的是,您的解决方案不符合要求,因为OP“无法修改fun的签名”。@AlexAntonov我的解决方案指的是专门处理标量或数组。将模板参数添加到fun
只是另一个建议。这两个是不相关的。
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);
}
void fun(const Obj& obj)
{
impl(obj.x);
}
void impl(const Type& x){...}
void impl(Type 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);
}