C++ 作为参数传递运算符
我想要一个计算2个布尔变量的函数(比如真值表) 例如: 自 T | F:T 然后C++ 作为参数传递运算符,c++,c,parameters,operator-keyword,C++,C,Parameters,Operator Keyword,我想要一个计算2个布尔变量的函数(比如真值表) 例如: 自 T | F:T 然后 myfunc('t', 'f', ||); /*defined as: bool myfunc(char lv, char rv, ????)*/ 应该返回true 如何传递第三个参数? (我知道可以将其作为char*传递,但随后我必须有另一个表来比较运算符字符串,然后执行我希望避免的操作) 是否可以在函数/方法中传递^(XOR)或| |(or)或&(AND)等运算符 提前感谢声明: template<c
myfunc('t', 'f', ||); /*defined as: bool myfunc(char lv, char rv, ????)*/
应该返回true
如何传递第三个参数?
(我知道可以将其作为char*传递,但随后我必须有另一个表来比较运算符字符串,然后执行我希望避免的操作)
是否可以在函数/方法中传递^(XOR)或| |(or)或&(AND)等运算符
提前感谢声明:
template<class Func> bool myfunc(char lv, char rv, Func func);
模板bool myfunc(char lv、char rv、Func Func);
或者,如果您需要单独链接:
bool myfunc(char lv, char rv, std::function<bool(bool,bool)> func);
bool myfunc(char lv、char rv、std::function func);
然后你可以打电话:
myfunc('t', 'f', std::logical_or<bool>());
myfunc('t','f',std::logical_或();
Ybanggabess发布了一个C++正确答案,你应该坚持下去。如果要传递运算符,函数将不起作用,但宏将起作用:
#define MYFUNC(lv, rv, op) ....
// Call it like this
MYFUNC('t', 'f', ||);
小心点,这很难实现。在C++中,函数参数需要一个内存地址来查找其对象,但编译时决定操作符。运算符将不是对象。所以您可以考虑使用宏来完成任务。您可以做的是定义返回特定类型的代理运算符
namespace detail {
class or {
bool operator()(bool a, bool b) {
return a || b;
}
};
class and {
bool operator()(bool a, bool b) {
return a && b;
}
};
// etc
class X {
or operator||(X x) const { return or(); }
and operator&&(X x) const { return and(); }
};
};
const detail::X boolean;
template<typename T> bool myfunc(bool a, bool b, T t) {
return t(a, b);
}
// and/or
bool myfunc(bool a, bool b, std::function<bool (bool, bool)> func) {
return func(a, b);
}
// example
bool result = myfunc(a, b, boolean || boolean);
名称空间详细信息{
阶级或{
布尔运算符()(布尔a,布尔b){
返回a | | b;
}
};
阶级和{
布尔运算符()(布尔a,布尔b){
返回a&b;
}
};
//等
X类{
或运算符| |(X)const{return或()
and运算符&(X)const{return and();}
};
};
常量细节::X布尔;
模板bool myfunc(bool a、bool b、T){
返回t(a,b);
}
//和/或
bool myfunc(bool a,bool b,std::function func){
返回函数(a,b);
}
//范例
bool result=myfunc(a,b,boolean | | boolean);
您可以使用模板传递复杂的逻辑表达式来实现此效果
此外,XOR运算符是按位的,而不是逻辑的-尽管实际上差异是零
但是,在C++ C++中存在lambda的原因,是因为这种东西在C++ 03中被吸收掉了。在现代C++中,< p>可以通过lambdas传递任何操作符。
更新1:建议的解决方案引入了@HolyBlackCat建议的小改进
#include <iostream>
template<class T, class F> void reveal_or(T a, T b, F f)
{
// using as function(a, b) instead of expression a || b is the same thing
if ( f(a, b) )
std::cout << a << " is || " << b << std::endl;
else
std::cout << a << " is not || " << b << std::endl;
}
template<class T> void reveal_or(T a, T b)
{
// reuse the already defined ||
reveal_or(a, b, [](T t1, T t2) {return t1 || t2; });
}
作为参数显式传递。我们可以传递任何东西,包括任何异国情调的废话
int main()
{
//同上:
揭示或('1','a',[](字符t1,字符t2){return t1 | | t2;});
//与上面相反
显示或('1','a',[](字符t1,字符t2){return!(t1 | | t2;)});
返回0;
}
如果我错了,请纠正我,但是重载运算符| |
和运算符&&
不是邪恶的吗?@比利:不是-为什么会这样?这与boost::bind中的_1和etc没有什么不同。对不起。。。没有看到这些是在类内部:P认为您破坏了包含&&
或| |
的每个表达式的短路语义!重载operator | |
和operator&
是有害的(因为这样的重载不再是惰性的,并且以未定义的顺序计算它们的参数),除非它们用于表达式模板(这不重要),就像在这种情况下。这不是真的。STL函子通常不是函数指针。我认为STL函子也是一个对象,所以它也有一个内存地址发送到函数参数中。这与此无关。可以重载运算符并将其传递给函数。碰巧,使用内置类型的预定义运算符无法实现这一点(没有充分的理由)。因此,将运算符传递给函数肯定是有效的——只是在这种非常特殊的情况下不起作用(除非您使用DeadMG所展示的技巧,否则它甚至适用于这种情况)。感谢Konrad。我不知道这个。我想知道:重载操作符->为操作符创建类的RTTI额外信息,所以对于编译器来说,它不是默认的操作符(编译器使用默认的二进制代码)。重载参数将编译为引用RTTI,以了解运算符如何处理其操作。因此它可以传递引用,而默认运算符不能传递。是吗?(我英语不太好。对不起。)我只是认为包含一个指向更多函数对象的链接会有所帮助,比如std::logical_或@ybungalobill。我尝试将myfunc
实现为return func(int(lv),rv(lv))
。但是像myfunc('1','3',std::plus())那样调用它
然后只返回1
,而不是4
。这不是要这样使用吗?@Patrick:myfunc
返回bool
,因此它不能返回4
。另外,'1'==49
和'3'==51
,因此我希望得到的答案是100=='d'
。将std::function
作为默认参数可以节省键入,但与普通lambda相比会给您带来额外的开销。我会编写两个重载,一个有3个参数,没有默认参数,另一个有两个参数,调用第一个。@HolyBlackCat是的,很好。@HolyBlackCat完成