0

Question Background

Consider a scenario in which I have two structs. Both consist of three fields for doubles. The only difference is the names used to refer to these fields. The first struct is for non-descript Tuples and the components are to be named x, y, and z. The second struct is for RGB values and the components are to be named red, green, and blue. Both of these structs need to have an interface defined for them such that operations such as vector/componentwise addition and scalar multiplication can be performed.

The Question

The problem? It seems terribly inelegant to copy and paste identical code for both of these structs only to change the naming scheme (x vs. red, y vs. green, z vs. blue). Ideally it would be possible in the interface function definitions to reference the fields of the struct (x or red) without having to name the field. Is this possible? If not then what other options are avaiable to me without changing the requirements? I include the struct definitions below along with some examples of their desired use with the possibly impossible interface I describe in this question.

Non-descript Tuple Struct

typedef struct
{
    /** The first coordinate */
    double x;

    /** The second coordinate */
    double y;

    /** The third coordinate */
    double z;

} Tuple;

RGB Tuple Struct

typedef struct
{
    /** The first coordinate */
    double red;

    /** The second coordinate */
    double green;

    /** The third coordinate */
    double blue;
} Tuple;

Example Usage

Tuple * genericTuple = createVector( 1, 2, 3 ); // create a generic Tuple
printf("%lf", genericTuple->x); // should print 1

Tuple * rgbTuple = createColor( 1, 2, 3 ); // create an rgbTuple
printf("%lf", rgbTuple->red); // should also print 1
1
  • What are the liabilities that you must overcome that prevents you from adopting the Adapter pattern?
    – jxh
    Commented Dec 21, 2022 at 22:57

2 Answers 2

4

This is IMHO not a "design patterns" question, but a C coding question, hence probably better suited for Stackoverflow than for Softwareengineering.SE.

Anyway, try this:

typedef struct
{
    union
    {
        double x;
        double red;
    };
    union
    {
        double y;
        double green;
    };
    union
    {
        double z;
        double blue;
    };
} Tuple;

That should do the trick.

1
  • 1
    Much thanks. I had considered that a possible solution might involve factory functions and couldn't rule out that it didn't belong under the "design pattern" rubric. But having seen your solution I agree. Commented Dec 21, 2022 at 20:51
3

I once was victim of a framework where someone decided to change a struct from having members h(orizontal) and v(ertical) to x and y. Constructors compiled but gave completely wrong results.

Don’t do this. Don’t treat these structs the same. If you have to, write two conversion functions.

If you feel you have to: Define a union with both structs as members. Accessing equal leading elements through different structs in a union is defined behaviour if the compiler knows about the union. But you obviously can’t have two structs with the same name and different element names both known to the compiler at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.