引用静态类在键值对中

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

Referencing a static class in a key-value pair

问题

我已经定义了代表不同运算符的类,并将它们设为静态的。我认为这是一种适当的方式来表示它们,因为实例化它们没有意义。

它们的声明如下:

static class BinaryOperator {
    int priority;
    virtual float apply(float left, float right) = 0;
};

static class Plus : BinaryOperator {
    float apply(float left, float right) override;
};

static class Times : BinaryOperator {
    float apply(float left, float right) override;
};

// 其他类似的操作符...

因为我有其他非平凡的运算符,它们可以具有多字符的符号,所以我想创建一个 map<string, BinaryOperator>,以便像这样轻松访问它们:

const map<string, dice::BinaryOperator> dice::Calculator::str_to_op_ = {
    {"+", dice::Plus},
    {"*", dice::Times},
    {"AC", dice::AC},
}

然而,当我尝试创建这个映射时,我得到以下错误:

类型名称不允许

这是有道理的。但是,我正在寻找一种引用这些静态类的单一实例的方法,这在理论上应该允许它们成为我的映射中的值。

我已经尝试创建指向这些类的指针,但似乎不起作用/我不知道如何正确地实现它。

英文:

I have defined classes that represent different operators, and made them static. I think that this would be a proper way to represent them, since it would not make sense to instantiate them.

They are declared like this

static class BinaryOperator {
        int priority;
        virtual float apply(float left, float right) = 0;
    };

static class Plus : BinaryOperator {
        float apply(float left, float right) override;
    };

static class Times : BinaryOperator {
        float apply(float left, float right) override;
    };

...

Since I have other, non-trivial operators, which can have multi-character symbols, I want to make a
map&lt;string, BinaryOperator&gt; that would make them easy to access, like this:

const map&lt;string, dice::BinaryOperator&gt; dice::Calculator::str_to_op_ = {
	(&quot;+&quot;, dice::Plus),
	(&quot;*&quot;, dice::Times),
	(&quot;AC&quot;, dice::AC),
}

However, when I want to create this map, I get the following error:

>type name not allowed

which makes sense. However, I am looking for a way to refer to the single instances of these static classes in the map, which should theoretically allow them to be the values in my map

I've tried making pointers to these classes, but it does not seem to work / I don't know how to properly do it.

答案1

得分: 1

不同于Java,C++不支持内部类。关键词“static”仅适用于对象和函数,而不适用于类型。从Java的角度来看,所有C++类都是"static"的。
在C++中,动态多态性不是那么受欢迎。通常有更好的抽象机制可用。此外,函数对象是现代C++中非常常见的概念。
所有对象(除了原始数组和字符字符串文字)默认按值传递。如果函数需要引用参数,这些参数必须在函数声明中标记为引用。
官方的初始化大括号是花括号{},而不是圆括号()。总的来说,我可以重写您的代码片段如下:

struct binary_operator {
    float (*apply)(int, float, float);
    int priority;
};

float product(int, float, float);

const std::unordered_map<std::string, binary_operator> str_to_op{
    {"+",
     {[](int pri, float op1, float op2) {
         if (pri)
             return op1 + op2;
         return 0;
     }}
    },

    {"*", {&product}}
};

您也可以使用std::function<void(int, float, float)>作为binary_operator::apply的类型,以获得更通用和灵活的代码。

如果您更多地了解您的需求,代码的大纲和设计可以发生 drastical改变。如果您已经知道所需的运算符的完整集合,甚至可以根据std::variant来定义您的binary_operator。这只是我从您的片段中读到的重新组织。

英文:

Unlike java, C++ does not support inner classes. The keyword static is only applicable to objects and functions, not types. All C++ classes are static in java terms.
Dynamic polymorphism is not that welcome in C++. There are usually better abstraction mechanisms available. More over function object is a very common concept on modern C++.
All objects (except raw arrays and char string literals) are - by default - transferred by value. If a function needs by-reference arguments, the arguments must be marked as references in the function declaration.
The official braces for initialization are curly pairs {} not round (). All in all, I can rewrite your snippet like:

struct binary_operator{
    float (*apply)(int, float, float);
    int priority;
};

float product (int, float, float);

const std::unordered _map&lt;std::string, binary_operator&gt; str_to_op{
    { &quot;+&quot;,
      { [](int pri, float op1, float op2) {
           if (pri)
               return op1+op2;
           return 0;
      }}
    },

    { &quot;*&quot;, {&amp;product} }
};

Instead of a function pointer, you may use std::function&lt;void(int,float,float)&gt; as the type of binary_operator::apply for more generic and flexible code.

The outline and design of code can drastically change if you know more about what you need. You can even define your binary_operator in terms of std::variant, if you already know the full set of operators needed. This much is a reorganization of what I could read from your snippet.

huangapple
  • 本文由 发表于 2023年3月9日 18:42:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75683494.html
匿名

发表评论

匿名网友

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

确定