#define c ++中的特殊运算符

Mat*_*nti 4 c++ operator-overloading operators c-preprocessor

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

我能做的一件基本事情就是找到一个免费的,未使用的运算符,并使用#define进行替换:

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

所以,如果我后来写了类似的东西

a!+b 
Run Code Online (Sandbox Code Playgroud)

使用myclass的a和b实例,它会工作.

现在,有没有办法定义它而不是运算符,具有一些功能?就像是:

#define a!+b -> a.operatorexclamativeplus(b)
Run Code Online (Sandbox Code Playgroud)

它会使翻译变得更少脏,并且可以允许这些新的"假运营商"中潜在的数量无限!

πάν*_*ῥεῖ 10

"现在,有没有办法定义它而不是运算符,具有某些功能?"

不,!+不会形成预处理器宏的有效(正常)标识符.字符是为语言内在运算符保留的.

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

c ++标准定义草案部分开始

16预处理指令

...
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,... )替换列表换行


更新:
我一直在尝试这一点,因为这实际上是一个有趣的问题,如果不是#define'宏,我们可以使用重载c ++中的类的内部运算符函数.

我发现实际上有可能(但可能是奇怪的和意外的行为)选项,通过链接它们并保持状态来重载内部运算符的组合.您新引入的运营商最接近的可能是:

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;
};
Run Code Online (Sandbox Code Playgroud)
int main() {
    Foo x;
    Foo z = !+x;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

产量

operator+()
operator!()
operatorexclamativeplus()
Run Code Online (Sandbox Code Playgroud)

查看实时样本.


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

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;
    }
    // ...
};
Run Code Online (Sandbox Code Playgroud)
int main() {
    Foo x;
    Foo y;
    Foo z = y !+ x;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

看到这个悲惨的失败.


结论:

  1. 内部运算符的一些重载组合在语法上可能是关于它们的优先级定义和维护左值的状态.
  2. 尝试重载内在的操作符行为,引入全新的语义可能不是一个好主意.

______________________________________________________________________________________

1) 关于标识符的前导下划线(_,__),请阅读本答案中提到的标准部分,但这些部分在语法上是有效的.

  • 我相信Deduplicator指的是[这个](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-ac-identifier). (2认同)