功能注册 + 多态性?

huangapple go评论76阅读模式
英文:

Function Registry + Polymorphism?

问题

I have a series of structures that all inherit from a base struct, and I also have a series of functions that take in a different child struct as an input.

我有一系列的结构体,它们都继承自一个基本结构体,我还有一系列的函数,这些函数以不同的子结构体作为输入。

I am trying to create a simple function registry/map using the various functions created. I assumed I would be able to use the base struct for the mapping of the functions, but when I go to insert the functions into the map I run into the error:

我试图创建一个简单的函数注册表/映射,使用各种已创建的函数。我以为我可以使用基本结构体来映射这些函数,但当我尝试将函数插入映射时,出现了错误:

error: no matching member function for call to 'insert' registry.insert({"func1", func1});

错误:没有匹配的成员函数可供调用'insert' registry.insert({"func1", func1});

Here is the code I have written at the moment:

以下是我目前编写的代码:

// Standard Includes
// 标准库包含
#include <functional>
#include <string>
#include <unordered_map>

struct Base
{
};

struct Test1 : Base
{
};

struct Test2: Base
{
};

inline bool func1(Test1 x)
{
return true;
}

inline bool func2(Test2 x)
{
return false;
}

using func = std::function<bool(Base)>;

inline std::unordered_map<std::string, func> functionRegistry()
{
std::unordered_map<std::string, func> registry;

registry.insert({&quot;func1&quot;, func1});
registry.insert({&quot;func2&quot;, func2});

return registry;

}

I would appreciate any help here if this is even possible (I assume it is, I am probably just doing something silly)!

如果可能的话,我会感激任何帮助(我认为这是可能的,我可能只是做了些傻事)!

英文:

I have a series of structures that all inherit from a base struct, and I also have a series of functions that take in a different child struct as an input.

I am trying to create a simple function registry/map using the various functions created. I assumed I would be able to use the base struct for the mapping of the functions, but when I go to insert the functions into the map I run into the error:

error: no matching member function for call to &#39;insert&#39; registry.insert({&quot;func1&quot;, func1});

Here is the code I have written at the moment:

// Standard Includes
#include &lt;functional&gt;
#include &lt;string&gt;
#include &lt;unordered_map&gt;

struct Base
{
};

struct Test1 : Base
{
};

struct Test2: Base
{
};

inline bool func1(Test1 x)
{
    return true;
}

inline bool func2(Test2 x)
{
    return false;
}

using func = std::function&lt;bool(Base)&gt;;

inline std::unordered_map&lt;std::string, func&gt; functionRegistry()
{
    std::unordered_map&lt;std::string, func&gt; registry;

    registry.insert({&quot;func1&quot;, func1});
    registry.insert({&quot;func2&quot;, func2});

    return registry;
}

I would appreciate any help here if this is even possible (I assume it is, I am probably just doing something silly)!

答案1

得分: 3

以下是翻译好的部分:

你展示的代码没有使用任何多态性。

有了这个说法,你可以通过将参数通过引用而不是按值传递来解决你的问题。然后,将lambda插入到映射中,使用适当的向下转型调用实际的函数:

bool func1(Test1& x)
{
    return true;
}

bool func2(Test2& x)
{
    return false;
}

using func = std::function<bool(Base&)>;

std::unordered_map<std::string, func> functionRegistry()
{
    std::unordered_map<std::string, func> registry;

    registry.insert({"func1", [](Base& x) { return func1(static_cast<Test1&>(x)); }});
    registry.insert({"func2", [](Base& x) { return func2(static_cast<Test2&>(x)); }});

    return registry;
}

请注意,我移除了inline说明符。除了改变函数的链接外,它仅仅是对编译器的建议。编译器会根据需要内联或不内联这些函数。

英文:

The code you show doesn't use any kind of polymorphism.

With that said, you can solve your problem by passing the arguments by reference instead of by value. Then insert lambdas into the map, which calls the actual functions using a suitable downcast:

bool func1(Test1&amp; x)
{
    return true;
}

bool func2(Test2&amp; x)
{
    return false;
}

using func = std::function&lt;bool(Base&amp;)&gt;;

std::unordered_map&lt;std::string, func&gt; functionRegistry()
{
    std::unordered_map&lt;std::string, func&gt; registry;

    registry.insert({&quot;func1&quot;, [](Base&amp; x) { return func1(static_cast&lt;Test1&amp;&gt;(x)); }});
    registry.insert({&quot;func2&quot;, [](Base&amp; x) { return func2(static_cast&lt;Test2&amp;&gt;(x)); }});

    return registry;
}

Note that I removed the inline specifier. Besides changing the linkage of the function, it's merely a suggestion to the compiler. The compiler will, or will not, inline the functions as it seems fit.

huangapple
  • 本文由 发表于 2023年5月15日 09:55:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/76250437.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定