简短回答:不要
我在评论中解释了为什么,主要原因是,它在您的代码中引入了歧义并降低了可读性,这与运算符的本意相反。只需使用不同的方法并提供选择用于此类的方法(如比较器)。在我打字的时候,人们发布了很好的例子,甚至有些人使用了一些元编程。
但是,对于科学来说,你可以。虽然您不能向运算符添加参数(二元运算符是二元运算符,并且似乎没有在某处添加第三个参数的语法),但您可以使运算符在不同的上下文中具有不同的含义(c++上下文,对于一行代码或由'{}'分隔的块)
这里使用构造/销毁顺序非常快速地完成(类似于不考虑线程安全的普通锁的实现):
对比如下:
Thing::thingSortingMode(Thing::thingSortingMode::alternateMode), Thing{1, 2} < Thing{3, 4};
在线运行此示例:http://cpp.sh/3ggrq
#include <iostream>
struct Thing {
struct thingSortingMode {
enum mode {
defaultMode,
alternateMode
};
mode myLastMode;
thingSortingMode(mode aMode) { myLastMode = Thing::ourSortingMode; Thing::ourSortingMode = aMode; std::cout << "\nmode: " << aMode << "\n"; }
~thingSortingMode() { Thing::ourSortingMode = myLastMode; std::cout << "\nmode: " << myLastMode << "\n";}
};
bool operator < (Thing another) {
switch (ourSortingMode) //I use an enum, to make the example more accessible, you can use a functor instead if you want
{
case thingSortingMode::alternateMode:
return myValueB < another.myValueB;
break;
default:
return myValueA < another.myValueA;
break;
}
}
static thingSortingMode::mode ourSortingMode;
int myValueA;
int myValueB;
};
Thing::thingSortingMode::mode Thing::ourSortingMode = Thing::thingSortingMode::defaultMode;
int main()
{
Thing a{1, 1}, b{0, 2}; // b < a in default mode, a < b in alternate mode
std::cout << (a < b); //false
{
Thing::thingSortingMode ctx(Thing::thingSortingMode::alternateMode);
std::cout << (a < b); //true
Thing::thingSortingMode(Thing::thingSortingMode::defaultMode), std::cout << (a < b), //false
Thing::thingSortingMode(Thing::thingSortingMode::alternateMode), std::cout << (a < b); //true
std::cout << (a < b); //true
}
std::cout << (a < b); //false
}
请注意,这种构造/破坏技巧可以管理任何类型的上下文状态,这里有一个更丰富的示例,包含 4 个状态和更多嵌套的上下文
在线运行此示例:http://cpp.sh/2x5rj
#include <iostream>
struct Thing {
struct thingSortingMode {
enum mode {
defaultMode = 1,
alternateMode,
mode3,
mode4,
};
mode myLastMode;
thingSortingMode(mode aMode) { myLastMode = Thing::ourSortingMode; Thing::ourSortingMode = aMode; std::cout << "\nmode: " << myLastMode << " -> " << aMode << "\n"; }
~thingSortingMode() { std::cout << "\nmode: " << Thing::ourSortingMode << " -> " << myLastMode << "\n"; Thing::ourSortingMode = myLastMode; }
};
static thingSortingMode::mode ourSortingMode;
};
Thing::thingSortingMode::mode Thing::ourSortingMode = Thing::thingSortingMode::defaultMode;
int main()
{
Thing::thingSortingMode ctx(Thing::thingSortingMode::mode3);
{
Thing::thingSortingMode ctx(Thing::thingSortingMode::alternateMode);
{
Thing::thingSortingMode ctx(Thing::thingSortingMode::mode4);
{
Thing::thingSortingMode ctx(Thing::thingSortingMode::defaultMode);
std::cout << "end sub 3 (mode 1)\n";
}
std::cout <<
(Thing::thingSortingMode(Thing::thingSortingMode::alternateMode), "this is the kind of things that might behave strangely\n") <<
(Thing::thingSortingMode(Thing::thingSortingMode::defaultMode), "here both are printed in mode 2, but it's a direct consequence of the order in which this expression is evaluated\n"); //note though that arguments are still constructed in the right state
std::cout << "end sub 2 (mode 4). Not that we still pop our states in the right order, even if we screwed up the previous line\n";
}
std::cout <<
(Thing::thingSortingMode(Thing::thingSortingMode::alternateMode), "this on the other hand (mode 2)\n"),
std::cout <<
(Thing::thingSortingMode(Thing::thingSortingMode::defaultMode), "works (mode 1)\n"); //but pay attention to the comma and in which order things are deleted
std::cout << "end sub 1 (mode 2)\n";
}
std::cout << "end main (mode 3)\n";
}
输出:
mode: 1 -> 3
mode: 3 -> 2
mode: 2 -> 4
mode: 4 -> 1
end sub 3 (mode 1)
mode: 1 -> 4
mode: 4 -> 1
mode: 1 -> 2
this is the kind of things that might behave strangely
here both are printed in mode 2, but it's a direct consequence of the order in which this expression is evaluated
mode: 2 -> 1
mode: 1 -> 4
end sub 2 (mode 4). Not that we still pop our states in the right order, even if we screwed up the previous line
mode: 4 -> 2
mode: 2 -> 2
this on the other hand (mode 2)
mode: 2 -> 1
works (mode 1)
mode: 1 -> 2
mode: 2 -> 2
end sub 1 (mode 2)
mode: 2 -> 3
end main (mode 3)
mode: 3 -> 1