使用类成员作为成员函数的默认参数

Using a class member as a default argument for a member function

本文关键字:成员 默认 参数 函数      更新时间:2023-10-16

除了手动重载相应的成员函数并使用成员作为参数调用第一个重载之外,还有没有其他方法?

我正在尝试类似的东西

class test
{
    string t1="test";
    testfun( string& val = this->t1 )
    { /* modify val somehow */ }
};

(测试:http://goo.gl/36p4CF)

目前,我想没有技术原因说明这不应该起作用。

  • 除了重载和手动设置参数之外,有没有解决方案可以做到这一点?
  • 为什么这不起作用,是否有技术原因?

[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:

每次调用函数时都会计算默认参数。 未指定函数参数的计算顺序。因此,函数的参数不应在默认值中使用 参数,即使它们没有被评估。

除了重载和手动设置参数之外,有没有解决方案可以做到这一点?

不,如果您希望默认参数依赖于另一个参数(包括 this )。虽然,在这种情况下,它没有意义,因为这是一个构造函数,并且在调用它之前不存在t1

为什么这不起作用,是否有技术原因?

因为未指定函数参数的计算顺序。若要允许默认参数中的参数值,需要更复杂的规则来确保在使用之前初始化每个参数。

你还没有说你想要实现什么。 我假设您需要每个实例都以特定的方式做出反应,具体取决于某个类变量。

但是,如果您不需要每个实例的行为,则可以使用静态变量。以下作品:

#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
    }
  }