#定义C ++中的特殊运算符 [英] #define a special operator in c++

查看:92
本文介绍了#定义C ++中的特殊运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我想在C ++中的两个对象之间组成一个特殊的运算符!+. 例如,我想使用!+,因为我认为它比任何其他运算符都有意义.

Say that I want to make up a special operator !+ in C++ between two objects. I would like to use !+, on example, because I think it is much more meaningful than any other operator.

我可以做的一件事是找到一个免费的,未使用的运算符,并使用#define进行替换:

One basic thing I could do is to find a free, unused operator and make the replacement work with a #define:

#define !+ %
class myclass 
{
  public:
   int operator %(myclass &c)
   {
      return 3;
   }
}

这样,如果我以后再写类似的东西

So that if I later write something like

a!+b 

使用myclass的a和b实例,它将起作用.

with a and b instances of myclass, it would work.

现在,有什么方法可以定义它,而不是通过带有某些功能的运算符来定义它?像这样:

Now, is there any way to define it instead that with an operator, with some function? Something like:

#define a!+b -> a.operatorexclamativeplus(b)

这将使翻译变得不那么脏乱了,并且可以使这些新的虚假运算符"的数量不受限制!

It would make the translation much less dirty, and would allow for a potentially unlimited number of these new "fake operators"!

推荐答案

现在,有什么方法可以定义它,而不是使用带有某些功能的运算符?"

否,!+不能形成预处理器宏的有效(常规)标识符.这些字符保留给语言内在运算符.

No, !+ doesn't form a valid (normal) identifier for a preprocessor macro. The characters are reserved for language intrinsic operators.

可用于宏定义的字符集是[_A-Za-z][_A-Za-z0-9]* regex语法 1 .

The set of characters you can use for macro definitions is [_A-Za-z][_A-Za-z0-9]*regex syntax1.

根据 c ++标准定义 草稿部分

16个预处理指令

...
控制行:
...
# define 标识符替换列表换行
# define identifier lparen标识符-listopt)替换列表换行
# define identifier lparen ...)替换列表换行符
# define identifier lparen标识符列表,...)替换列表换行

16 Preprocessing directives

...
control-line:
...
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list, ... ) replacement-list new-line


更新:
我已经做了一些实验,因为这实际上是一个有趣的问题,如果没有#define宏,我们可以对c ++中的类使用重载内在运算符.


UPDATE:
I've been experimenting with this a bit, since this actually is an interesting question, and if not #define'd macros, we can use overloading intrinsic operator functions for classes in c++.

我发现实际上有可能(但可能很奇怪且出乎意料的)选项通过链接它们并保持状态来重载内在运算符的组合.您可以为新引入的运营商获得的最接近的东西是:

I have found there actually are possible (but may be weird and unexpectedly behaving) options, to overload combinations of intrinsic operators by chaining them and keep state. The closest thing you can get for your newly introduced operator could be:

class Foo {
    enum OpState { None , PlusState , NotState };   
public:
   Foo& operator+() {
       cout << "operator+()" << endl;
       opState = PlusState;
       return *this;
   }
   Foo& operator!() {
       cout << "operator!()" << endl;
       switch(opState) {
       case PlusState:
           operatorexclamativeplus();
           break;       
       default:
           opState = NotState;
           break;       
       }
       return *this;
   }    
private:
    Foo& operatorexclamativeplus() {
       cout << "operatorexclamativeplus()" << endl;
       opState = None;
       return *this;
    }
    Foo& operatorexclamativeplus(const Foo& rhs) {
       cout << "operatorexclamativeplus(const Foo& rhs)" << endl;
       opState = None;
       return *this;
    }   
    OpState opState;
};


int main() {
    Foo x;
    Foo z = !+x;
    return 0;
}

输出

operator+()
operator!()
operatorexclamativeplus()

请参见实时示例.

但是,由于 运算符优先级规则 ,这仅适用于一元运算符(!的优先级高于二进制+),您想要的形式似乎实际上不是可以实现的:

Though, because of operator precedence rules, this would work only for unary operators (! has higher precedence than binary +), the form you want to have doesn't seem to be actually achievable:

class Foo {
    // ...
public:
    // Provide an additional binary 'operator+()'
    friend Foo& operator+(Foo& lhs, const Foo& rhs) {
        cout << "operator+(Foo& lhs, const Foo& rhs)" << endl;
        if(lhs.opState == NotState) {
            return lhs.operatorexclamativeplus(rhs);
        }
        return lhs;
    }
    // ...
};


int main() {
    Foo x;
    Foo y;
    Foo z = y !+ x;
    return 0;
}

看到此惨状失败.

结论:

  1. 某些内在运算符的重载组合可能是 关于它们的优先级定义,在语法上是可能的,并且 保持左值的状态.
  2. 尝试重载内在函数可能不是一个好主意 操作员行为,引入了全新的语义.
  1. Some overloaded combinations of intrinsic operators might be syntactically possible, regarding their precedence definitions, and maintaining state of lvalues.
  2. It's probably not a very good idea, to try to overload intrinsic operator behavior, introducing completely new semantics.

______________________________________________________________________________________

1) 关于标识符的前划线(___),请阅读

1) Regarding leading underscores (_,__) for identifiers please read the standards sections mentioned in this answer, these are syntactically valid though.

这篇关于#定义C ++中的特殊运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆