现在我有一个switch语句,它接受一个输入并选择以下操作之一:
选项1
for(; i < queue_size; ++i)
{
prepared->setString(i+1, queue.at(i).model);
}
选项2
for(; i < queue_size; ++i)
{
prepared->setString(i+1, queue.at(i).manufacturer);
}
选项3
for(; i < queue_size; ++i)
{
prepared->setString(i+1, queue.at(i).name);
}
在PHP中,你可以做同样的事情:
$queue[i][$member];
$ member可以设置为“name”,“manufacturer”等。
有没有办法在C ++中做类似或更强大的东西?
提前感谢您的任何帮助/建议!
答案 0 :(得分:4)
如果您没有C ++ 11,请使用C ++ 11 std::function或boost::function:
std::map<YourSwitchType, std::function<void(void)> functionMap;
然后定义诸如
之类的函数void manufacturString() {
for(; i < queue_size; ++i) {
prepared->setString(i+1, queue.at(i).manufacturer);
}
}
针对每种情况,并使用这些填充地图。
functionMap[someSwitchValue] = std::bind(&ThisType::manufactureString, this);
然后你可以打电话给他们:
functionMap[someSwitchValue]();
这种方法的一个优点是它不会限制您使用成员函数。您可以将非成员函数,仿函数,静态成员和非成员函数放在同一个映射中。唯一的限制是在绑定之后,它们返回void并且不带参数(这是特定于此示例的)。
答案 1 :(得分:2)
您可以使用map
从属性名称到指向成员的指针执行此操作。但它有点工作(你需要自己创建映射),语法有点毛茸茸。 (并且您希望以这种方式解决的所有成员必须属于同一类型。)
演示:
#include <iostream>
#include <map>
struct Foo {
std::string name;
std::string address;
};
typedef std::string Foo::* FooMemPtr;
typedef std::map<std::string, FooMemPtr> propmap;
int main()
{
propmap props;
props["name"] = &Foo::name;
props["address"] = &Foo::address;
/* ... */
Foo myfoo;
myfoo.*(props["name"]) = "myname";
myfoo.*(props["address"]) = "myaddress";
std::cout << myfoo.*(props["address"]) << std::endl;
std::cout << myfoo.*(props["name"]) << std::endl;
}
答案 2 :(得分:1)
如果您可以使用枚举而不是字符串,那么您可以访问从枚举值索引的名称,制造商等。这取决于你需要的动态。
答案 3 :(得分:0)
使用STL map执行此操作。它就像在PHP中一样工作。
答案 4 :(得分:0)
一个选项是将提取器仿函数传递给函数:
#include <string>
#include <vector>
#include <boost/bind.hpp>
struct Some {
std::string model, manufacturer, name;
};
struct Prepared {
void setString(size_t, std::string const&);
};
template<class Extractor>
void foo(Extractor extract) {
Prepared* prepared = 0;
std::vector<Some> queue;
size_t i, queue_size = queue.size();
for(; i < queue_size; ++i) {
prepared->setString(i+1, extract(queue.at(i)));
}
}
int main() {
// C++03
foo(boost::bind(&Some::model, _1));
foo(boost::bind(&Some::manufacturer, _1));
foo(boost::bind(&Some::name, _1));
// C++11
foo([](Some const& some){ return some.model; });
foo([](Some const& some){ return some.manufacturer; });
foo([](Some const& some){ return some.name; });
}
答案 5 :(得分:0)
你可以使用成员变量点来做这种事情(也有成员函数指针)。 boost绑定函数更通用,但这最终是他们在底层所做的事情(至少在这种情况下)。
#include <iostream>
#include <string>
struct item
{
std::string a, b;
};
//the really ugly syntax for a pointer-to-member-variable
typedef std::string item::*mem_str;
//show each member variable from the list
void show_test( item * objs, size_t len, mem_str var )
{
for( size_t i=0; i < len; ++i )
std::cout << objs[i].*var << std::endl;
}
int main()
{
//create some test data
item test[2];
test[0].a = "A-Zero";
test[0].b = "B-Zero";
test[1].a = "A-One";
test[1].b = "B-One";
//show variables
show_test( test, 2, &item::a );
show_test( test, 2, &item::b );
return 0;
}