gpt4 book ai didi

c++ - 在进行大量类似的方法调用时避免定义宏

转载 作者:行者123 更新时间:2023-11-30 02:26:14 26 4
gpt4 key购买 nike

下面的代码使用了#define 宏。我想避免这种情况,但我看不到使用 C++ 功能的方法 and 更具可读性。该代码用于测试将 PoorLegacyClass 的两个实例合并为一个的类 ClassUnderTest。这个 PoorLegacyClass 有很多 getter 和 setter,出于测试目的,我需要调用很多 setter(或者我是这样吗?)。

简而言之,而不是写作

a.setValueX(20);
b.setValueX(30);

我想写这样的东西

set(a, b, ValueX, 20, 30);
// or
set<ValueX>(a, 20, b, 30);
// or even
set(a, b, &PoorLegacyClass::setValueX, 20, 30);

下面的代码与我现在使用的代码类似:

#include <boost/test/unit_test.hpp>

#include "ClassUnderTest.h"

BOOST_AUTO_TEST_SUITE(Test_ClassUnderTest);

#define SETTER_A_B(fieldname, valueA, valueB)\
a.set##fieldname(valueA);\
b.set##fieldname(valueB);

struct TestContext
{
PoorLegacyClass a, b;
};

BOOST_FIXTURE_TEST_CASE(ClassUnderTest_meaningful_description1, TestContext)
{
SETTER_A_B(ValueX, 20, 30);
auto result = ClassUnderTest().merge(a, b);

BOOST_TEST(20 == result.getValueX());
}

BOOST_FIXTURE_TEST_CASE(ClassUnderTest_meaningful_description2, TestContext)
{
SETTER_A_B(ValueY, 21, 37);
auto result = ClassUnderTest().merge(a, b);

BOOST_TEST(21 + 37 == result.getValueY());
}

BOOST_FIXTURE_TEST_CASE(ClassUnderTest_meaningful_description3, TestContext)
{
SETTER_A_B(ValueZ, 12, 83);
auto result = ClassUnderTest().merge(a, b);

BOOST_TEST(12 + 83 == result.getValueZ());
}

BOOST_FIXTURE_TEST_CASE(ClassUnderTest_meaningful_description4, TestContext)
{
SETTER_A_B(ValueY, 212, 37);
SETTER_A_B(ValueX, 20, 30);
auto result = ClassUnderTest().merge(a, b);

BOOST_TEST(a.getValueY() == result.getValueY());
}

// more test cases that are similar to those above

BOOST_AUTO_TEST_SUITE_END();

虽然我将来会重构 PoorLegacyClass 这不是这个问题的主题。不过,我想知道的是如何避免使用 #define 宏。

最佳答案

既然您愿意接受语法 set(a, b, &PoorLegacyClass::setValueX, 20, 30);,那么实现这样的 set 应该很容易:

template <class T>
void set(PoorLegacyClass &a, PoorLegacyClass &b, void (PoorLegacyClass::*setter)(T), T valForA, T valForB)
{
(a.*setter)(valForA);
(b.*setter)(valForB);
}

您还可以使 valFor 参数在非推导上下文中使用 T,这样 T 只能推导来自 setter 和隐式转换发生在值上:

template <class T>
struct NonDeduced { using type = T; }

template <class T>
void set(PoorLegacyClass &a, PoorLegacyClass &b, void (PoorLegacyClass::*setter)(T), typename NonDeduced<T>::type valForA, typename NonDeduced<T>::type valForB)

关于c++ - 在进行大量类似的方法调用时避免定义宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43116773/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com