如果未找到映射条目,则返回特定的映射条目而不是map :: end

时间:2016-07-12 14:13:50

标签: c++ dictionary function-pointers

在switch语句中,如果没有其他情况适用,则可以指定默认返回值。 我想用std :: map做类似的事情,但我不确定它是否可行: 如果没有键适合搜索,我可以使地图返回特定值/条目而不是map :: end吗?

示例(以下是我最喜欢做的事情 - 我知道代码不起作用):

std::map<std::string, void* (*) (DataObject*)> commands; //Mapping functions to keys
commands["Test"] = function(DataObject d){doSomething();}
commands[Nothing else applies] = function(DataObject d){doSomethingElse();}

commands.find("Test")(someDataObject); // doSomething(); happens
commands.find("blabla")(someDataObject); //doSomethingElse(); happens because no other entry was found

这样的事情会成为可能吗?

(另外,我在这个例子中使用函数指针的方式可能根本不起作用 - 我可以使用cpp11的lambda表达式来完成我想做的事吗?)

我不想使用switch子句,也不想使用if(m.find(x) != m.end())子句,也不想更多if-else。

2 个答案:

答案 0 :(得分:0)

您可以使用具有默认值的自己的仿函数:

struct MyFunctor: public std::function<void(DataObject*)> {

    template <typename F>
    MyFunctor (F &&f) : std::function<void(DataObject*)> (std::forward<F> (f)) { }

    MyFunctor () : std::function<void(DataObject*)> (doSomethingElse) { }

};

假设doSomethingElse是已经定义的函数。

然后你就可以做到:

std::map<std::string, MyFunctor> commands; //Mapping functions to keys
commands["Test"] = [] (DataObject *) { }; // Assign from lambda

DataObject *myDataObject= new DataObject();
commands["Not Defined"] (myDataObject); // Call doSomethingElse

您可以使用MyFunctor的模板轻松拥有不同的默认值(在编译时定义):

template <void (*DefaultFn) (DataObject*)>
struct MyFunctor: public std::function<void(DataObject*)> {

    template <typename F>
    MyFunctor (F &&f) : std::function<void(DataObject*)> (std::forward<F> (f)) { }

    MyFunctor () : std::function<void(DataObject*)> (DefaultFn) { }

};

std::map<std::string, MyFunctor<doSomethingElse>> commands;

答案 1 :(得分:0)

不,你没有std::map的功能,因为std::map::find()当找不到密钥并且你无法取消引用它时,返回等于end()的迭代器。因此,您需要使用if( m.find( "blah" ) == m.end() )子句或使用其他std::map或使用您需要的功能编写自己的类。

您可能拥有特殊值类型,默认状态将具有您需要的功能,然后通过std::map::operator[]而不是std::map::find()访问它,但这会产生副作用 - 对于您搜索的每个键,新条目将是添加到地图中。我怀疑这比一个if()条款更好解决方案,但这取决于你。