将此代码转换为宏
Converting this code be turned into a macro
我目前的示例代码:
a = b;
我希望我的宏实现的新逻辑:
if(b != "" and b != " ")
a = b;
所以如果可能的话,我想要一个这样的宏:
a = VALUE(b);
a
和 b
属于 CString
类型。我知道我可以通过编写 inline
方法来实现这一点,但我想知道是否可以使用 MACRO?
我有几个变量,我想在分配值时应用此逻辑。
根据敦促我使用 inline
函数的评论,并根据我的具体要求,我最终执行了以下操作。
- 这是我的
struct
对象,其定义无法更改:
typedef struct tagPublicTalkInfo
{
CString strAwayCong1;
CString strAwayCong2;
CString strAwayBrother1;
CString strAwayBrother2;
CString strAwayTalkNumber1; // AJT v20.1.9
CString strAwayTalkNumber2; // AJT v20.1.9
CString strChairman;
CString strCong;
CString strHosp;
CString strReader;
CString strBrother;
CString strTheme;
CString strWTConductor; // AJT v10.7.2
CString strInterpreter; // AJT v16.2.1
CString strMisc; // AJT v16.2.1
CString strWatchtowerStudyTheme; // AJT v17.0.5
CString strServiceTalkTheme; // AJT v17.0.7
CString strBibleVersesReader; // AJT v20.0.1
CString strVideoHost; // AJT v20.1.4
CString strVideoCohost; // AJT v20.1.4
CString strOpeningPrayer; // AJT v20.1.6
CString strClosingPrayer; // AJT v20.1.6
int iSongStart; // AJT v20.0.1
int iSongMiddle; // AJT v20.0.1
int iSongEnd; // AJT v20.0.1
int iThemeNumber; // AJT v20.1.6
} S_TALK_INFO;
- 我添加了这个新的
inline
方法:
void SetValue(CString& rStrCurrentValue, CString strNewValue)
{
if (strNewValue != _T("") && strNewValue != _T(" "))
rStrCurrentValue = strNewValue;
}
- 最后,我调整了我的
SetWeekendMeetingInfo
方法,现在它看起来像:
void CWeekendMeetingDlg::SetWeekendMeetingInfo(S_TALK_INFO &rsTalkInfo)
{
//m_sWMInfo = rsTalkInfo;
SetValue(m_sWMInfo.strAwayCong1, rsTalkInfo.strAwayCong1);
SetValue(m_sWMInfo.strAwayCong2, rsTalkInfo.strAwayCong2);
SetValue(m_sWMInfo.strAwayBrother1, rsTalkInfo.strAwayBrother1);
SetValue(m_sWMInfo.strAwayBrother2, rsTalkInfo.strAwayBrother2);
SetValue(m_sWMInfo.strAwayTalkNumber1, rsTalkInfo.strAwayTalkNumber1);
SetValue(m_sWMInfo.strAwayTalkNumber2, rsTalkInfo.strAwayTalkNumber2);
SetValue(m_sWMInfo.strChairman, rsTalkInfo.strChairman);
SetValue(m_sWMInfo.strCong, rsTalkInfo.strCong);
SetValue(m_sWMInfo.strHosp, rsTalkInfo.strHosp);
SetValue(m_sWMInfo.strReader, rsTalkInfo.strReader);
SetValue(m_sWMInfo.strBrother, rsTalkInfo.strBrother);
SetValue(m_sWMInfo.strTheme, rsTalkInfo.strTheme);
SetValue(m_sWMInfo.strWTConductor, rsTalkInfo.strWTConductor);
SetValue(m_sWMInfo.strInterpreter, rsTalkInfo.strInterpreter);
SetValue(m_sWMInfo.strMisc, rsTalkInfo.strMisc);
SetValue(m_sWMInfo.strWatchtowerStudyTheme, rsTalkInfo.strWatchtowerStudyTheme);
SetValue(m_sWMInfo.strServiceTalkTheme, rsTalkInfo.strServiceTalkTheme);
SetValue(m_sWMInfo.strBibleVersesReader, rsTalkInfo.strBibleVersesReader);
SetValue(m_sWMInfo.strVideoHost, rsTalkInfo.strVideoHost);
SetValue(m_sWMInfo.strVideoCohost, rsTalkInfo.strVideoCohost);
SetValue(m_sWMInfo.strOpeningPrayer, rsTalkInfo.strOpeningPrayer);
SetValue(m_sWMInfo.strClosingPrayer, rsTalkInfo.strClosingPrayer);
m_sWMInfo.iSongStart = rsTalkInfo.iSongStart;
m_sWMInfo.iSongMiddle = rsTalkInfo.iSongMiddle;
m_sWMInfo.iSongEnd = rsTalkInfo.iSongEnd;
m_sWMInfo.iThemeNumber = rsTalkInfo.iThemeNumber;
}
它似乎可以正常工作。正如我所说,我无法更改 struct
对象的定义,但如果您认为可以改进这种方法,请通知我。
对 S_TALK_INFO
结构中的 bulk-copy 个连续字段的 CString
个建议:
您的 SetValue
函数的名称并未反映它的作用。我会将其替换为:
bool IsValid(const CString& str)
{
return !str.IsEmpty() && !_istspace(str[0]);
}
这是犹太洁食吗?您将不得不维护第一个和最后一个字段的名称,但现在您必须维护更多...
void CWeekendMeetingDlg::SetWeekendMeetingInfo(S_TALK_INFO &rsTalkInfo)
{
for (CString* pSrc = &rsTalkInfo.strAwayCong1, *pDst = &m_sWMInfo.strAwayCong1;
pSrc <= &rsTalkInfo.strClosingPrayer;
pDst++, pSrc++)
{
if(IsValid(*pSrc))
*pDst = *pSrc;
}
// the "int" stuff
}
Re:UB - 这有帮助吗(对于每个连续的对)?
static_assert(offsetof(S_TALK_INFO, strAwayCong2) - offsetof(S_TALK_INFO, strAwayCong1)
== sizeof(CString));
我目前的示例代码:
a = b;
我希望我的宏实现的新逻辑:
if(b != "" and b != " ")
a = b;
所以如果可能的话,我想要一个这样的宏:
a = VALUE(b);
a
和 b
属于 CString
类型。我知道我可以通过编写 inline
方法来实现这一点,但我想知道是否可以使用 MACRO?
我有几个变量,我想在分配值时应用此逻辑。
根据敦促我使用 inline
函数的评论,并根据我的具体要求,我最终执行了以下操作。
- 这是我的
struct
对象,其定义无法更改:
typedef struct tagPublicTalkInfo
{
CString strAwayCong1;
CString strAwayCong2;
CString strAwayBrother1;
CString strAwayBrother2;
CString strAwayTalkNumber1; // AJT v20.1.9
CString strAwayTalkNumber2; // AJT v20.1.9
CString strChairman;
CString strCong;
CString strHosp;
CString strReader;
CString strBrother;
CString strTheme;
CString strWTConductor; // AJT v10.7.2
CString strInterpreter; // AJT v16.2.1
CString strMisc; // AJT v16.2.1
CString strWatchtowerStudyTheme; // AJT v17.0.5
CString strServiceTalkTheme; // AJT v17.0.7
CString strBibleVersesReader; // AJT v20.0.1
CString strVideoHost; // AJT v20.1.4
CString strVideoCohost; // AJT v20.1.4
CString strOpeningPrayer; // AJT v20.1.6
CString strClosingPrayer; // AJT v20.1.6
int iSongStart; // AJT v20.0.1
int iSongMiddle; // AJT v20.0.1
int iSongEnd; // AJT v20.0.1
int iThemeNumber; // AJT v20.1.6
} S_TALK_INFO;
- 我添加了这个新的
inline
方法:
void SetValue(CString& rStrCurrentValue, CString strNewValue)
{
if (strNewValue != _T("") && strNewValue != _T(" "))
rStrCurrentValue = strNewValue;
}
- 最后,我调整了我的
SetWeekendMeetingInfo
方法,现在它看起来像:
void CWeekendMeetingDlg::SetWeekendMeetingInfo(S_TALK_INFO &rsTalkInfo)
{
//m_sWMInfo = rsTalkInfo;
SetValue(m_sWMInfo.strAwayCong1, rsTalkInfo.strAwayCong1);
SetValue(m_sWMInfo.strAwayCong2, rsTalkInfo.strAwayCong2);
SetValue(m_sWMInfo.strAwayBrother1, rsTalkInfo.strAwayBrother1);
SetValue(m_sWMInfo.strAwayBrother2, rsTalkInfo.strAwayBrother2);
SetValue(m_sWMInfo.strAwayTalkNumber1, rsTalkInfo.strAwayTalkNumber1);
SetValue(m_sWMInfo.strAwayTalkNumber2, rsTalkInfo.strAwayTalkNumber2);
SetValue(m_sWMInfo.strChairman, rsTalkInfo.strChairman);
SetValue(m_sWMInfo.strCong, rsTalkInfo.strCong);
SetValue(m_sWMInfo.strHosp, rsTalkInfo.strHosp);
SetValue(m_sWMInfo.strReader, rsTalkInfo.strReader);
SetValue(m_sWMInfo.strBrother, rsTalkInfo.strBrother);
SetValue(m_sWMInfo.strTheme, rsTalkInfo.strTheme);
SetValue(m_sWMInfo.strWTConductor, rsTalkInfo.strWTConductor);
SetValue(m_sWMInfo.strInterpreter, rsTalkInfo.strInterpreter);
SetValue(m_sWMInfo.strMisc, rsTalkInfo.strMisc);
SetValue(m_sWMInfo.strWatchtowerStudyTheme, rsTalkInfo.strWatchtowerStudyTheme);
SetValue(m_sWMInfo.strServiceTalkTheme, rsTalkInfo.strServiceTalkTheme);
SetValue(m_sWMInfo.strBibleVersesReader, rsTalkInfo.strBibleVersesReader);
SetValue(m_sWMInfo.strVideoHost, rsTalkInfo.strVideoHost);
SetValue(m_sWMInfo.strVideoCohost, rsTalkInfo.strVideoCohost);
SetValue(m_sWMInfo.strOpeningPrayer, rsTalkInfo.strOpeningPrayer);
SetValue(m_sWMInfo.strClosingPrayer, rsTalkInfo.strClosingPrayer);
m_sWMInfo.iSongStart = rsTalkInfo.iSongStart;
m_sWMInfo.iSongMiddle = rsTalkInfo.iSongMiddle;
m_sWMInfo.iSongEnd = rsTalkInfo.iSongEnd;
m_sWMInfo.iThemeNumber = rsTalkInfo.iThemeNumber;
}
它似乎可以正常工作。正如我所说,我无法更改 struct
对象的定义,但如果您认为可以改进这种方法,请通知我。
对 S_TALK_INFO
结构中的 bulk-copy 个连续字段的 CString
个建议:
您的 SetValue
函数的名称并未反映它的作用。我会将其替换为:
bool IsValid(const CString& str)
{
return !str.IsEmpty() && !_istspace(str[0]);
}
这是犹太洁食吗?您将不得不维护第一个和最后一个字段的名称,但现在您必须维护更多...
void CWeekendMeetingDlg::SetWeekendMeetingInfo(S_TALK_INFO &rsTalkInfo)
{
for (CString* pSrc = &rsTalkInfo.strAwayCong1, *pDst = &m_sWMInfo.strAwayCong1;
pSrc <= &rsTalkInfo.strClosingPrayer;
pDst++, pSrc++)
{
if(IsValid(*pSrc))
*pDst = *pSrc;
}
// the "int" stuff
}
Re:UB - 这有帮助吗(对于每个连续的对)?
static_assert(offsetof(S_TALK_INFO, strAwayCong2) - offsetof(S_TALK_INFO, strAwayCong1)
== sizeof(CString));