简体   繁体   English

为具有对象或对象数组作为成员的类运行不同的代码

[英]Run different code for a class that has either an object or an array of objects as a member

I have a method that takes an object as parameter 我有一个方法,将对象作为参数

void fun(const Obj& obj)

Obj can be defined in two different ways: Obj可以用两种不同的方式定义:

struct Obj
{
   Type x;
};

and

struct Obj
{
   Type x[42];
};

I cannot modify the definitions of Obj (ie I can't rename the classes). 我无法修改Obj的定义(即我无法重命名类)。 Also, I can't modify the signature of fun and I'd rather not use preprocessor directives inside of fun . 此外,我不能修改的签名fun ,我宁可不使用内部预处理指令fun Is there a way to use metaprogramming to make this compile and work regardless of which definition of Obj is included: 有没有办法使用元编程来进行编译和工作,无论包含哪个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 
}

? Is there a way to do it without C++11 features? 有没有办法在没有C ++ 11功能的情况下完成它?

You could pick a specialization of a template based on decltype(obj.x) : 您可以根据decltype(obj.x)选择模板的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);
}

Possible C++03 way is a member detector trait class that checks for existence of Type Obj::x . 可能的C ++ 03方式是检查Type Obj::x是否存在的成员检测器特征类。 This time, template parameter of impl would be bool so you can simply pass the result of the check: 这次, 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);
}

This can be done by a second call to an implementation function fun_impl that also takes obj.x as an argument. 这可以通过第二次调用实现函数fun_impl来完成,该函数也将obj.x作为参数。 This function specializes to scalars or arrays by two overloads, the latter accepting a reference to an array, so maintaining the array size as well: 此函数通过两个重载专门用于标量或数组,后者接受对数组的引用,因此也保持数组大小:

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

This works in C++03 and does not require any traits features or SFINAE. 这适用于C ++ 03,不需要任何特征功能或SFINAE。 See also live example , where the remaining parts use C++11 for convenience. 另请参见实例 ,其余部分使用C ++ 11以方便使用。

If obj only contains x , you can drop it as an argument from fun_impl . 如果obj只包含x ,则可以将其作为fun_impl的参数fun_impl I left it here for the more general case where obj might have other members as well. 我把它留在这里是为了更一般的情况,其中obj也可能有其他成员。

Note that fun itself is given as a template here; 请注意, fun本身在此处作为模板给出; I guess this is what you need to do anyway since you are dealing with different definitions of Obj . 我想这是你需要做的事情,因为你正在处理不同的Obj定义。

My suggestion is to use function overloading. 我的建议是使用函数重载。 You don't need metaprogramming/templates in your case: 在您的情况下,您不需要元编程/模板:

void fun(const Obj& obj)
{
   impl(obj.x);
}

void impl(const Type& x){...}
void impl(Type x[]){...}

If Obj::x is declared as Type x then the first impl() version will be called. 如果将Obj::x声明为Type x则将调用第一个impl()版本。 And similarly in another case the second impl() version will be called. 同样在另一种情况下,将调用第二个impl()版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何从在其中创建的不同类对象中访问类对象的成员函数? - How do you access member functions of a class object from within a different class object that has been created in it? class具有动态数组成员的类 - class has class with dynamic array member 使用不同的类存储对象成员变量的引用 - Store a reference to an objects member variable with a different class 未知大小的数组作为类成员,用于在运行时创建数组对象(对象创建时) - array of unknown size as class member for making objects of array at runtime(object creating time) 使用成员函数对类对象数组进行排序 - Sorting array of class objects using member function 指向对象和初始化成员值的指针数组 - Array of Pointers to class objects and initializing member values 对象数组的指针的语法作为另一个类的成员 - Syntax of a pointer for array of objects as member of another class 是否为对象数组立即调用构造函数作为类的成员? - Is the constructor called immediately for an array of objects as a member of the class? 从同一类中的另一个成员对象访问成员对象 - Accessing member objects from another member object within the same class C ++将类成员动态定义为对象或对另一个成员的引用 - C++ dynamically define class member as either an object or a reference to another member
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM