【问题标题】:Making an Operator Overload context specific使运算符重载上下文特定
【发布时间】:2017-05-05 07:56:29
【问题描述】:

我在业余时间学习 C++,并且正在实现一个重载下标 /[] 运算符的类。现在,我希望能够将两个或多个参数传递给下标运算符,如下所示(用逗号分隔):

myObject[i,j,...],其中参数可以是 strings 或 ints

我发现 C++ 不允许下标运算符接受多个参数。但是,我在this thread 中阅读了有关重载逗号运算符的信息,作为该“问题”的替代解决方案。

在示例中,逗号运算符使用非常特定的签名进行重载,带有两个自定义 Enum,但我可以看到对于通用类型对重载逗号运算符不是一个好主意(这将是我的用例)。

由于我对 C++ 的了解有限,这让我很好奇是否有可能将逗号运算符重载的“范围”或使用限制在特定情况或上下文中,例如,仅在下标运算符重载中定义,给我我感兴趣的功能,而不会对其他地方造成干扰。

【问题讨论】:

    标签: c++ operator-overloading comma-operator


    【解决方案1】:

    您不能将常规函数/运算符限制在上下文中,但由于命名空间,您可以按范围限制它。

    enum class E {A, B};
    
    struct C
    {
        int operator [](const std::pair<E, E>& p) const
        {
            return data[static_cast<int>(p.first) * 2 + static_cast<int>(p.second)];
        }
        std::array<int, 4> data{{1, 2, 3, 4}};
    };
    
    namespace comma
    {
        std::pair<E, E> operator , (E lhs, E rhs) { return { lhs, rhs }; }
    }
    
    int main()
    {
        C c;
    
        {
            using namespace comma; // operator , is valid here.
    
            std::cout << c[E::A, E::B] << std::endl;
            auto p = (E::A, E::B); // but also here :/ p = {E::A, E::B}
            static_cast<void>(p);
        }
        {
            std::cout << c[E::A, E::B] << std::endl; // result in c[E::B]
            auto p = (E::A, E::B); // p = E::B
            static_cast<void>(p);
        }
    }
    

    Demo

    作为替代方案,您可以使用常规方法,operator () 方法(可以带多个参数),使用std::pair/std::tuple 作为参数(需要在调用站点额外封闭{})。

    【讨论】:

    • 这太酷了!谢谢你。所以,使用命名空间,我理论上也可以使用例如std::pair&lt;int, int&gt; operator , (int lhs, int rhs) { return { lhs, rhs }; } 在该范围内,而不会在该范围之外破坏逗号运算符的其他用途,对吧?
    • operator, 必须至少有一个类或枚举类型的参数。所以int/int 是非法的。
    【解决方案2】:

    不,不可能只为特定上下文重载运算符。您仍然可以根据您的运算符类型限制其使用。

    【讨论】:

      【解决方案3】:

      当你重载一个操作符时,你指定了哪些类型可以与这个操作符一起使用。因此,最好使用类中定义的类型来设计它。

      class YourClass
      {
      public:
      class YourType{};
      };
      
      pair<YourClass::YourType, YourClass::YourType> operator , (YourClass::YourType p1, YourClass::YourType p2)
      {
          return make_pair(p1, p2);
      }
      

      但是如果你需要某种形式的泛化,你可以使用模板和模板特化。

      【讨论】:

      • 是的,这也是我问题中的链接示例提供的内容。我只是想知道对于一般类型的参数是否也可以安全地执行此操作,但我想这是不可能的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      相关资源
      最近更新 更多