Amr Osman
Amr Osman

Reputation: 119

using std::tie to compare structs

I have this code in my application in Qt C++. My operator== for comparing structs always returns false even if they are equal. What's wrong with my code?

Here is a code snippet that has the problem:

struct pSettings
{
    int speciality;
    bool autoCompleteByWord;
    bool showChronicConditions;
    bool showNavArrows;
    bool smallScreenMode;
    bool simpleExamination;
    bool alwaysSave;
    bool inLinePatientList;
    double newVisitPrice;
    double followVisitprice1;
    double followVisitprice2;
    double followVisitprice3;
    double followVisitprice4;
    int autosaveinterval;
    bool  autoSave ;
    bool minimizeToTray;
    int selectedTheme;
    QString textColor;
    QString topBGColor;
    QString bottomBGColor;
    QString altWinColor;
    QString buttonColor;
    QString altButtonColor;
    QString textBGColor;
    QString borderColor1;
    QString borderColor2;
    QString altButtonColorHover;
    QString buttonColorHover;
    QString buttonColorDisabled;
    QString buttonBorderColorHover;
    QString comboBGcolor;
    QString buttonTextColor;
    QString comboTextColor;
    double lOffSet,tOffSet;

    QString defaultFont;
    double defaultFontSize;
    bool defaultFontBold;

    QString textboxFont;
    double textboxFontSize;
    bool textboxFontBold;

    int maxFollowUps;
    bool autoClosePrintDlg;
    int maxFollowUpsPerProblem;
    bool autoSetnewAfterMaxPerProblemIsReached;
    int checkoutDate;
    int checkoutTime;
    bool enableVisualEffects;

    bool operator==(const pSettings& psettings) const
    {
        return std::tie(
                    speciality,
                    autoCompleteByWord,
                    showChronicConditions,
                    showNavArrows,
                    smallScreenMode,
                    simpleExamination,
                    alwaysSave,
                    inLinePatientList,
                    newVisitPrice,
                    followVisitprice1,
                    followVisitprice2,
                    followVisitprice3,
                    followVisitprice4,
                    autosaveinterval,
                    autoSave ,
                    minimizeToTray,
                    selectedTheme,
                    textColor,
                    topBGColor,
                    bottomBGColor,
                    altWinColor,
                    buttonColor,
                    altButtonColor,
                    textBGColor,
                    borderColor1,
                    borderColor2,
                    altButtonColorHover,
                    buttonColorHover,
                    buttonColorDisabled,
                    buttonBorderColorHover,
                    comboBGcolor,
                    buttonTextColor,
                    comboTextColor,
                    lOffSet,
                    tOffSet,
                    defaultFont,
                    defaultFontSize,
                    defaultFontBold,
                    textboxFont,
                    textboxFontSize,
                    textboxFontBold,
                    maxFollowUps,
                    autoClosePrintDlg,
                    maxFollowUpsPerProblem,
                    autoSetnewAfterMaxPerProblemIsReached,
                    checkoutDate,
                    checkoutTime,
                    enableVisualEffects) ==
                std::tie(psettings.speciality,
                         psettings.autoCompleteByWord,
                         psettings.showChronicConditions,
                         psettings.showNavArrows,
                         psettings.smallScreenMode,
                         psettings.simpleExamination,
                         psettings.alwaysSave,
                         psettings.inLinePatientList,
                         psettings.newVisitPrice,
                         psettings.followVisitprice1,
                         psettings.followVisitprice2,
                         psettings.followVisitprice3,
                         psettings.followVisitprice4,
                         psettings.autosaveinterval,
                         psettings.autoSave ,
                         psettings.minimizeToTray,
                         psettings.selectedTheme,
                         psettings.textColor,
                         psettings.topBGColor,
                         psettings.bottomBGColor,
                         psettings.altWinColor,
                         psettings.buttonColor,
                         psettings.altButtonColor,
                         psettings.textBGColor,
                         psettings.borderColor1,
                         psettings.borderColor2,
                         psettings.altButtonColorHover,
                         psettings.buttonColorHover,
                         psettings.buttonColorDisabled,
                         psettings.buttonBorderColorHover,
                         psettings.comboBGcolor,
                         psettings.buttonTextColor,
                         psettings.comboTextColor,
                         psettings.lOffSet,
                         psettings.tOffSet,
                         psettings.defaultFont,
                         psettings.defaultFontSize,
                         psettings.defaultFontBold,
                         psettings.textboxFont,
                         psettings.textboxFontSize,
                         psettings.textboxFontBold,
                         psettings.maxFollowUps,
                         psettings.autoClosePrintDlg,
                         psettings.maxFollowUpsPerProblem,
                         psettings.autoSetnewAfterMaxPerProblemIsReached,
                         psettings.checkoutDate,
                         psettings.checkoutTime,
                         psettings.enableVisualEffects);
    }

};

Upvotes: 1

Views: 2755

Answers (2)

neurocore
neurocore

Reputation: 29

Your can use high-order macrofunction for that:

#define ITEMS                   \
ITEM(int,  speciality)          \
ITEM(bool, autoCompleteByWord)  \
...
ITEM(int,  checkoutTime)        \
LAST(bool, enableVisualEffects)

#define ITEM(x,y) x y;
#define LAST(x,y) ITEM(x,y)

struct pSettings
{
    ITEMS
}

#define ITEM(x,y) y,
#define LAST(x,y) y

auto mytie() const
{
    return std::tie
    (
        ITEMS
    );
}

It is a good idea to write ITEMS definition inside the separate file

Upvotes: -1

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275385

Somewhere in the teo long lists you have an error where they are not identical. You violated DRY (Don't Repeat Yourself).

In C++14:

auto mytie() const {
  return std::tie( /* ... fields */ );
}

Then write == using that.

In C++11 you have to write mytie(blah const& self) as a local (stateless) lambda to keep things reasonable.

If this fails, then they compare non-equal because they differ in a way you did not notice.

Upvotes: 6

Related Questions