简体   繁体   English

C ++:将未知的并集传递给函数作为参数

[英]C++: passing unknown union to function as argument

So I have something like this: 所以我有这样的事情:

struct FoodType {
    union {
        int fat = 2;
    } Apple;
    union {
        int fat = 3;
    } Banana;
} FoodType;

And I want to write a function that takes an "unknown" FoodType as argument. 我想编写一个函数,将“未知” FoodType作为参数。

void eatFood(FoodType type) { /* do something */ }

How can this be implemented? 如何实现呢?

Alternatives to the enum solution for what you provide in your question is instantiation: 您在问题中提供的枚举解决方案的替代方法是实例化:

#include <iostream>

struct FoodType {
    FoodType(int f) : fat(f) {}
    int getFat() { return fat; }
    int fat;
};

void eatFood(const FoodType& type) { std::cout << "I ate " << type.getFat() << " grams of fat\n"; }

int main() {
    FoodType apple(2);
    eatFood(apple);
    FoodType banana(3);
    eatFood(banana);
}

or, for more complex situations, polymorphism can be used, but here it seems like overkill: 或者,对于更复杂的情况,可以使用多态性,但是在这里看起来有点过头了:

#include <iostream>

struct FoodType {
    virtual int getFat() const = 0;
};

struct Apple: FoodType {
    int getFat() const { return 2; }
};

struct Banana: FoodType {
    int getFat() const { return 3; }
};

void eatFood(const FoodType& type) { std::cout << "I ate " << type.getFat() << " grams of fat\n"; }

int main() {
    Apple apple;
    eatFood(apple);
    Banana banana;
    eatFood(banana);
}

Is this what you're after? 这是你所追求的吗?

struct Food {
  enum class Type { Apple, Banana };
  int fat = 2;
  Type type = Apple;
};

Here you can specify the type, and you can store the fat value as well. 您可以在此处指定类型,也可以存储fat值。

In the question's code, there is a union with a single member. 在问题的代码中,有一个由单个成员组成的union union need more than one member to be useful, the members are stored at the same memory address, so you can only use one of them at the time. union需要多个成员才能使用,这些成员存储在相同的内存地址中,因此您当时只能使用其中一个。 And both unions declared a variable with the same name and function, it seems to me that you'd only need one of those. 而且两个联合都声明了具有相同名称和功能的变量,在我看来,您只需要其中一个即可。

However, if you have something more complicated in mind, and you really need a union , then you should try something like this: 但是,如果您有一些更复杂的想法,并且确实需要union ,那么您应该尝试这样的事情:

struct Food {
  enum class Type { Apple, Banana };
  Type type = Apple;
  union {
    int banana;
    double apple;
  };
};
Food food;
food.type = Food::Type::Apple;
food.apple = 2;

Here, you can use either the banana element or the apple element, and you'd use the type element to know which one to use. 在这里,您可以使用banana元素或apple元素,并且可以使用type元素来知道要使用哪个元素。

But if you need that, you'd be better off using the new std::variant (or boost::variant) if your compiler doesn't yet support it). 但是,如果需要的话,最好使用新的std::variant (如果编译器尚不支持,则使用boost :: variant)。

Judging from your comments you want enums. 从您的评论来看,您需要枚举。 C++ has enums: C ++具有枚举:

enum FoodType
{
    Apple,
    Banana
};

void EatFood(const FoodType & foodType)
{
    switch (foodType)
    {
    case Apple:
        /* do something */
        break;
    case Banana:
        /* do something */
        break;
    default:
        /* handle invalid value */
        break;
    }
}

If you need those integer values, do this: 如果需要这些整数值,请执行以下操作:

enum FoodType
{
    Apple=2,
    Banana=3
};

If you want strict typing, do this: 如果要严格输入,请执行以下操作:

enum class FoodType
{
    Apple=2,
    Banana=3
};

(And then in EatFood you have to use FoodType::Apple and FoodType::Banana.) (然后在EatFood中,您必须使用FoodType :: Apple和FoodType :: Banana。)

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM