Return 特定的地图条目而不是 map::end 如果没有找到地图条目

Return specific map entry instead of map::end if no map entry was found

在 switch 语句中,如果 none 其他情况适用,您可以指定默认值 return。 我想用 std::map 做一些类似的事情,但我不确定是否可行: 如果没有键适合搜索,我可以将地图 return 设为特定的 value/entry 而不是 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。

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

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;

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

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