我正在尝试创建一个指向具有默认参数的成员函数的指针。当我通过这个函数指针调用时,我不想为默认参数指定一个参数。根据标准,这是不允许的,但我以前从未发现任何标准不允许我无法以其他符合方式做的事情。到目前为止,我还没有找到执行此操作的方法。
这是说明我要解决的问题的代码:
class MyObj
{
public:
int foo(const char* val) { return 1; }
int bar(int val = 42) { return 2; }
};
int main()
{
MyObj o;
typedef int(MyObj::*fooptr)(const char*);
fooptr fp = &MyObj::foo;
int r1 = (o.*fp)("Hello, foo.");
typedef int(MyObj::*barptr)(int);
barptr bp1 = &MyObj::bar;
int r2 = (o.*bp1)(); // <-- ERROR: too few arguments for call
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar; // <-- ERROR: Can't convert from int(MyObj::*)(int) to int(MyObj::*)(void)
int r3 = (o.*bp2)();
return 0;
}
如果我不想为默认参数指定任何值,关于如何在符合 C++ 中执行此操作的任何想法?
编辑:澄清一下限制。我不想在调用或任何 typedef 中指定任何默认参数。例如,我不想这样做:
typedef int(MyObj::*barptr)(int = 5);
...我也不想这样做:
typedef int(MyObj::*barptr)(int);
...
(o.barptr)(5);
最佳答案
在您的示例中期望函数指针按照您期望的方式工作是相当奇怪的。 “默认参数”是一个纯粹的编译时概念,它是一种语法糖。尽管默认参数是在函数声明或定义中指定的,但它们实际上与函数本身无关。实际上,默认参数在调用点被替换,即它们在调用者的上下文中处理。从函数的角度来看,用户提供的显式参数与编译器隐式提供的默认参数没有区别。
另一方面,函数指针是运行时实体。它们在运行时初始化。在运行时默认参数根本不存在。 C++ 中没有“运行时默认参数”这样的概念。
一些编译器允许您在函数指针声明中指定默认参数,如
void foo(int);
int main() {
void (*pfoo)(int = 42) = foo;
pfoo(); // same as 'pfoo(42)'
}
但这不是标准的 C++,而且这似乎不是您要查找的内容,因为您希望“默认参数”值在运行时根据指针指向的函数更改。
只要你想坚持使用真正的函数指针(而不是函数对象,又名仿函数),直接的解决方法就是为你的函数提供一个不同名称的无参数版本,如
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
int bar_default() { return bar(); }
};
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar_default;
int r3 = (o.*bp2)();
return 0;
}
当然,这远非优雅。
实际上有人可以争辩说,我在上面对 bar_default 所做的事情可能是由编译器隐式完成的,作为一种语言特性。例如。给定类定义
class MyObj
{
public:
...
int bar(int val = 42) { return 2; }
...
};
人们可能希望编译器允许以下内容
int main()
{
MyObj o;
typedef int (MyObj::*barptr2)();
barptr2 bp2 = &MyObj::bar;
int r3 = (o.*bp2)();
return 0;
}
指针初始化实际上会强制编译器为 MyObj::bar 隐式生成一个“适配器”函数(与我之前示例中的 bar_default 相同),以及将 bp2 设置为指向该适配器。但是,目前 C++ 语言中还没有这样的功能。引入这样的东西需要付出比乍看起来更多的努力。
另请注意,在最后两个示例中,指针类型为 int (MyObj::*)(),这与 int (MyObj::*)(int)。这实际上是您的一个问题(因为您在示例中都尝试过):您希望它如何工作?使用 int (MyObj::*)() 指针?或者使用 int (MyObj::*)(int) 指针?
关于c++ - 带有默认参数的成员函数指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2225330/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了