2

现在我有一个 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 设置为“名称”、“制造商”等。

有没有办法在 C++ 中做类似或更强大的事情?

提前感谢您的任何帮助/建议!

4

6 回答 6

4

如果您没有 C++11,请使用 C++11 std::functionboost::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 并且不接受任何参数(这是特定于本示例的)。

于 2012-05-18T08:03:27.160 回答
3

您可以使用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;
}
于 2012-05-18T08:07:16.523 回答
1

如果您可以使用枚举而不是字符串,那么您可以访问从枚举值索引的名称、制造商等。这取决于你需要多动态。

于 2012-05-18T08:05:57.227 回答
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; });
}
于 2012-05-18T08:14:58.197 回答
0

使用STL 映射来执行此操作。它就像你在 PHP 中所做的那样工作。

于 2012-05-18T07:59:32.447 回答
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;
}
于 2012-05-18T11:51:48.327 回答