具有默认参数的成员函数指针 [英] Member-Function Pointers With Default Arguments

查看:174
本文介绍了具有默认参数的成员函数指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个指向具有默认参数的成员函数的指针。当我通过该函数指针进行调用时,我不想为默认参数指定参数。根据标准,这是不允许的,但是我从未发现过该标准所禁止的,我无法以其他某种方式进行的操作。到目前为止,我还没有找到一种方法。

I am trying to create a pointer to a member function which has default arguments. When I call through this function pointer, I do not want to specify an argument for the defaulted argument. This is disallowed according to the standard, but I have never before found anything that the standard disallowed that I could not do in some other conformant way. So far, I have not found a way to do this.

以下代码说明了我要解决的问题:

Here is code illustrating the problem I'm trying to solve:

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 ++中执行此操作的任何想法如果我不想为默认参数指定任何值?

Any ideas on how to do this in conformant C++ if I do not want to specify any values for the defaulted arguments?

编辑:稍微澄清一下限制。我不想在调用或任何typedef中指定任何默认参数。例如,我不想这样做:

To clarify the restrictions a bit. I do not want to specify any default arguments either in the call or in any typedef. For example, I do not want to do this:

typedef int(MyObj::*barptr)(int = 5);

...我也不想这样做:

...nor do I want to do this:

typedef int(MyObj::*barptr)(int);
...
(o.barptr)(5);


推荐答案

期望函数指针指向是很奇怪的以您期望他们在示例中工作的方式工作。 默认参数是一个纯粹的编译时概念,它是语法糖的一种形式。尽管默认参数是在函数声明或定义中指定的,但它们实际上与函数本身无关。实际上,默认参数在调用时被替换,即在 caller 的上下文中进行处理。从函数的角度来看,用户提供的显式参数与编译器隐式提供的默认参数之间没有区别。

It would be rather strange to expect the function pointers to work the way you expect them to work in your example. "Default argument" is a purely compile-time concept, it is a form of syntactic sugar. Despite the fact that default arguments are specified in the function declaration or definition, they really have nothing to do with the function itself. In reality default arguments are substituted at the point of the call, i.e. they are handled in the context of the caller. From the function's point of view there's no difference between an explicit argument supplied by the user or a default one implicitly supplied by the compiler.

另一方面,函数指针是运行时实体。它们在运行时初始化。在运行时,默认参数根本不存在。在C ++中没有运行时默认参数这样的概念。

Function pointers, on the other hand, are run-time entities. They are initialized at run time. At run-time default arguments simply don't exist. There's no such concept as "run-time default arguments" in C++.

某些编译器将允许您在函数指针声明中指定默认参数,如

Some compilers will allow you to specify default arguments in function pointer declaration, as in

void foo(int);

int main() {
   void (*pfoo)(int = 42) = foo;
   pfoo(); // same as 'pfoo(42)'
}

但这不是标准的C ++而且这似乎不是您要查找的内容,因为您希望在运行时根据指针所指向的函数更改默认参数值。

but this is not standard C++ and this does not appear to be what you are looking for, since you want the "default argument " value to change at run time depending on the function the pointer is pointing to.

只要您想使用真正的函数指针(而不是函数对象,也就是函子),立即的解决方法就是为您提供函数名称的无参数版本,例如

As long as you want to stick with genuine function pointers (as opposed to function objects, aka functors) the immediate workaround would be for you to provide a parameter-less version of your function under a different name, as in

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 所做的工作可能已经被编译器作为语言功能隐式完成了。例如。给定的类定义

One can actually argue that what I did above with bar_default could have been implicitly done by the compiler, as a language feature. E.g. given the class definition

class MyObj 
{ 
public: 
  ...
  int bar(int val = 42) { return 2; } 
  ...
}; 

一个人可能希望编译器允许以下操作

one might expect the compiler to allow the following

int main() 
{ 
  MyObj o; 

  typedef int (MyObj::*barptr2)(); 
  barptr2 bp2 = &MyObj::bar;
  int r3 = (o.*bp2)(); 
  return 0; 
} 

其中指针初始化实际上将迫使编译器隐式生成适配器 MyObj :: bar 的函数(与上一个示例中的 bar_default 相同),并设置 bp2 指向该适配器。但是,目前C ++语言中没有此类功能。并且要引入类似的内容比乍看起来似乎需要付出更多的努力。

where the pointer initialization would actually force the compiler to implicitly generate an "adapter" function for MyObj::bar (same as bar_default in my previous example), and set bp2 to point to that adaptor instead. However, there's no such feature in C++ language at this time. And to introduce something like that would require more effort than it might seem at the first sight.

还要注意,在最后两个示例中,指针类型为 int(MyObj :: *)(),与 int(MyObj :: *)(int)不同。这实际上是一个问题(因为您在示例中都尝试过):希望它如何工作?使用 int(MyObj :: *)()指针吗?还是使用 int(MyObj :: *)(int)指针?

Also note that in the last two examples the pointer type is int (MyObj::*)(), which is different from int (MyObj::*)(int). This is actually a question to you (since you tried both in your example): how would you want it to work? With an int (MyObj::*)() pointer? Or with a int (MyObj::*)(int) pointer?

这篇关于具有默认参数的成员函数指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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