使用类成员作为成员函数的默认参数
Posted
技术标签:
【中文标题】使用类成员作为成员函数的默认参数【英文标题】:Using a class member as a default argument for a member function 【发布时间】:2015-01-15 23:04:37 【问题描述】:除了手动重载相应的成员函数并以该成员为参数调用第一个重载之外,还有其他方法吗?
我正在尝试类似的东西
class test
string t1="test";
testfun( string& val = this->t1 )
/* modify val somehow */
;
(测试一下:http://goo.gl/36p4CF)
目前我想这不应该工作没有技术原因。
除了重载和手动设置参数外,是否有其他解决方案? 为什么这不起作用,是否有技术原因?【问题讨论】:
只使用“test”,它不会降低性能或增加内存使用量,因为它会保持不变。 @self:但t1
不是恒定的;所以用一个常量替换它不一定会做同样的事情。
我的意思是使用字符串文字“test”
@self:是的,我知道。这与发布代码的意图不同,即使用成员变量的当前值,而不是常量值。
“测试它”链接格式严重错误。您正在使用构造函数作为测试函数,这似乎是个坏主意。并且该函数修改了参数,但您使用const char*
(文字字符串)调用它。提供MCVE时要小心
【参考方案1】:
你还没有说出你想要达到的目标。我假设您需要每个实例以特定方式做出反应,具体取决于某个类变量。
但是,如果您不需要每个实例的行为,那么您可以使用静态变量。以下作品:
#include <iostream>
using namespace std;
struct test
static string t1;
void say(const string &val=t1)
cout << val << "!" << endl;
;
string test::t1;
int main()
cout << "Hello World" << endl;
test::t1 = string("asd");
test a;
a.say();
a.say("bla");
test::t1 = string("blahblah");
a.say();
return 0;
...这意味着test
类的所有对象都将使用静态字符串t1
作为它们的默认值。
你可以稍微“破解”一下,把它当作丑陋的哨兵:
void say(const string &val=t1)
if (&val == &t1)
// They are using the default value, so act as you want
else
// they are providing a value
【讨论】:
@thigg 免责声明:您还没有说出您想要实现的目标。是的,我不明白您的需求是什么,只是想对static
与非提供一些见解。好的,我会稍微修改一下我的答案,但我认为它对于解决您的问题的人仍然非常有用。
是的,也许它对正在搜索的人有好处。总的来说,我想这里很有教育意义。【参考方案2】:
[dcl.fct.default]/8:
关键字
this
不得用于成员函数的默认参数。
这是一般问题的一种特殊情况:您不能在参数的默认参数中引用其他参数。即
void f(int a, int b = a)
格式不正确。也会如此
class A
int j;
;
void f(A* this, int i = this->j)
这基本上是编译器将void f(int i = j)
形式的成员函数转换成的内容。这源于这样一个事实,即函数参数和后缀表达式(构成对象参数)的求值顺序是未指定的。 [dcl.fct.default]/9:
每次调用函数时都会评估默认参数。 未指定函数参数的求值顺序。因此,函数的参数不应在默认情况下使用 参数,即使它们没有被评估。
【讨论】:
是的,我看到了问题所在。但是语法糖会很好;) @thigg 不能否认这一点。 :D 在您的情况下,重载应该以合理的可读性完成这项工作。 是的,但我必须为几个功能这样做,所以很烦人;)【参考方案3】:除了重载和手动设置参数之外,有没有办法这样做?
不,如果您希望默认参数依赖于另一个参数,包括this
,则需要重载。虽然在这种情况下,它没有意义,因为这是一个构造函数,并且t1
在它被调用之前并不存在。
为什么这不起作用,是否有技术原因?
因为没有指定函数参数的评估顺序。要在默认参数中允许参数值,您需要更复杂的规则来确保每个参数在使用之前都已初始化。
【讨论】:
以上是关于使用类成员作为成员函数的默认参数的主要内容,如果未能解决你的问题,请参考以下文章