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);
}