相同的外部结构只有一个功能之间的区别
Same outer structure only one difference between functions
除了修改的变量之外,我有许多函数做大致相同的事情
struct example
{
std::string name;
std::string category;
};
using ObjName = std::string;
using Value = std::string;
bool updateName(const ObjName &name, const Value& value) ...
bool updateCategory(const ObjName &name,const Value& value)
{
// boost optional pointing to struct reference
auto obj = findOjb(name);
if (obj)
{
obj.get().category = value; // variable name changes
return true;
}
return false;
}
我想知道的是我可以做些什么来组合代码?我怀疑它会涉及模板,可能是叛徒/函子,但我不确定如何处理它的任何想法?
重新设计 Daerst 的代码以删除那个可怕的offsetof
,转而支持指向成员的指针......
struct example
{
std::string name;
std::string category;
};
bool updateVariable(const ObjName &name, std::string example::*member, std::string const &value)
{
// your code ...
// Access
rule.get().*member = value
// rest of your code
}
bool updateName(const ObjName &oldname, const ObjName& newName)
{
return updateVariable(name, &example::name, newName));
}
bool updateCategory(const ObjName &name, Category &cat)
{
return updateVariable(name, &example::category, cat));
}
你可以使用 lambdas:
template <typename Accessor>
bool updateVariable(const ObjName& name, const Value& value, Accessor access) {
auto obj = findObj(name);
if (obj)
{
access(obj.get()) = value;
return true;
}
return false;
}
bool updateCategory(const ObjName& name, const Value& value) {
return updateVariable(name, value,
[](Example& e) -> Value& { return e.category; });
}
这比指向成员的指针解决方案更灵活一些。您可以通过让 lambda 执行设置而不是返回引用来使其更加灵活。
您可以使用以下特征:
#include <string>
#include <assert.h>
struct example
{
std::string name;
int category;
};
struct nameDesc
{
typedef std::string valuetype;
static void set(example& obj, const valuetype& val)
{
obj.name = val;
}
};
struct categoryDesc
{
typedef int valuetype;
static void set(example& obj, const valuetype& val)
{
obj.category = val;
}
};
example test; // just for testing...
example& findObj(const std::string &name)
{
// just for testing...
return test;
}
template <typename V>
bool update(const std::string &objName, const typename V::valuetype& value)
{
example& obj = findObj(objName);
V::set(obj, value);
return true;
}
bool updateName(const std::string &objName, const std::string& value) { return update<nameDesc>(objName, value); }
bool updateCategory(const std::string &objName, int value) { return update<categoryDesc>(objName, value); }
int main()
{
update<nameDesc>("objname", "asdf");
update<categoryDesc>("objname", 1234);
assert(test.name == "asdf");
assert(test.category == 1234);
updateName("objname", "qwer");
updateCategory("objname", 7890);
assert(test.name == "qwer");
assert(test.category == 7890);
return 0;
}
如果可能的话,我鼓励你看看boost::spirit/BOOST_FUSION_ADAPT_STRUCT。
有点笨拙,但这可能是使用 offsetof
的解决方案(未经测试的代码):
struct example
{
std::string name;
std::string category;
};
bool updateVariable(const size_t offset, std::string value)
{
// your code ...
// ASSIGNMENT: get address, apply offset and assign value
*(&rule.get() + offset) = cat;
// rest of your code
}
bool updateName(const ObjName &oldname, const ObjName& newName)
{
return updateVariable(offsetof(struct example, name), newName));
}
bool updateCategory(const ObjName &name, Category &cat)
{
return updateVariable(offsetof(struct example, category), cat));
}
我假设ObjName
和Category
是string
typedef
的,或者可以隐式转换。
您仍然需要为每个成员变量添加一个单行函数,如果您想坚持硬编码的结构,这很难C++中躲避。您可能需要考虑将整个结构定义转换为数据,例如从文件加载,从而打开其他可能性。
相关文章:
- C++03 和 C++11 之间的c_str功能规范的差异
- 如何在两个类之间使用功能指针
- 在 OpenCV 中计算 SURF 功能之间的距离
- 是否有C 功能来计算两个索引之间的距离
- C 11和C 14之间的功能签名差异
- 我应该如何分享该过程和多个DLL之间的功能列表
- C 如何在实例之间访问类成员功能
- 静态成员功能和全局功能之间有什么不同
- 编译时,复制构造函数/复制分配和正常功能调用优化之间是否存在任何区别
- unix中选择和轮询系统调用之间的功能差异
- 在模板功能和自动类型扣除之间进行选择
- VC :在功能之间传递多个数组
- 主要功能和状态之间的通信
- 在C++中,是什么导致了这两个功能之间的差异
- 相同的外部结构只有一个功能之间的区别
- 以下 2 个代码片段之间是否有任何功能差异
- "功能1"和"功能2"之间的歧义(C++)
- c ++:TCP服务器"bind"功能失败(errno 98),如果我在两次连续应用程序启动之间没有等待足够的时间
- C++中各种自定义比较器功能之间的差异
- 有谁知道免注册COM和拖放功能之间可能存在哪种关系