Updating all members of a struct in database This function is part of our company's project code.
The following function updates six members of struct CpGSMTimeDelayQuery -- t14_cp, T14_au, Tdl_fib_f, Tul_fib_f, Tdl_cp_f, Tul_cp_f -- in the database. 

It contains six similar blocks. These blocks do the same thing: read a specific register, calculate the member value using a specific formula, and then set database.

typedef unsigned int    Uint32;

void FpgaAdapter::UpdateCpGsmDelayTime()
{
    Uint32 regvalue(0);
    Uint32 result(0);
    float tmp;

    if (ReadReg(0x98, regvalue)) {
        result = (float)regvalue * 6.51;
        SetStructElementToDB("CpGSMTimeDelayQuery", "t14_cp", result);
    }   

    if (ReadReg(0x99, regvalue)) {
        result = (float)regvalue * 6.51;
        SetStructElementToDB("CpGSMTimeDelayQuery", "T14_au", result);
    }   

    if (ReadReg(0x9c, regvalue)) {
        result = (float)regvalue * 6.51;
        SetStructElementToDB("CpGSMTimeDelayQuery", "Tdl_fib_f", result);
    }   

    if (ReadReg(0x9d, regvalue)) {
        result = (float)regvalue * 6.51;
        SetStructElementToDB("CpGSMTimeDelayQuery", "Tul_fib_f", result);
    }   

    if (ReadReg(0xa0, regvalue)){
        tmp = (0xff &amp; regvalue) * 32.55;
        result = ( 0xff &amp; (regvalue&gt;&gt;8)) * 1000 + (Uint32)tmp;
        SetStructElementToDB("CpGSMTimeDelayQuery", "Tdl_cp_f", result);
    }   

    if (ReadReg(0xa1, regvalue)){
        tmp = (0xff &amp; regvalue) * 32.55;
        result = (0xff &amp; (regvalue&gt;&gt;8)) * 1000 + (Uint32)tmp;
        SetStructElementToDB("CpGSMTimeDelayQuery", "Tul_cp_f", result);
    }
}


How can I refactor this function so that I can use a for loop to update all members of the struct instead of using six similar blocks?

My thought:
Create a map which key is member name, and value is register address and calculation formula. Then loop through the map to update all members in the database.

But, I don't know how to do that because I am not familiar with C++.
One way you can simplify this code and also make it more forward compatible with future addition of new fields is by using a simple array that stores the register keys, database field names and a pointer to a function that transforms the register value in the adequate way. You should also be able to remove all duplicate code in the process.

The following example uses auto and C++11 lambdas to keep everything close together, but you can easily replace that by plain functions if you don't have access to a C++11 compiler. Also note that I don't have enough context to pick more meaningful names other than commands and xform, but you should be able to find better ones.

void FpgaAdapter::UpdateCpGsmDelayTime()
{
    auto xform1 = [](Uint32 regValue) { 
        return static_cast&lt;Uint32&gt;(regValue * 6.51); 
    };

    auto xform2 = [](Uint32 regValue) { 
        const float tmp = (0xff &amp; regValue) * 32.55;
        return (0xff &amp; (regvalue &gt;&gt; 8)) * 1000 + static_cast&lt;Uint32&gt;(tmp);
    };

    static const struct {
        Uint32 regKey;
        const char * dbField;
        Uint32 (*transform)(Uint32);
    } commands[] = {
        { 0x98, "t14_cp",    xform1 },
        { 0x99, "T14_au",    xform1 },
        { 0x9c, "Tdl_fib_f", xform1 },
        { 0x9d, "Tul_fib_f", xform1 },
        { 0xa0, "Tdl_cp_f",  xform2 },
        { 0xa1, "Tul_cp_f",  xform2 }
    };

    for (int i = 0; i &lt; sizeof(commands) / sizeof(commands[0]); ++i) {
        Uint32 regValue = 0;
        if (ReadReg(commands[i].regKey, regValue)) {
            const Uint32 result = commands[i].transform(regValue);
            SetStructElementToDB("CpGSMTimeDelayQuery", commands[i].dbField, result);
        }
    }
}