C ++ ... когда все аргументы имеют значения по умолчанию - PullRequest
4 голосов
/ 16 января 2010

Я думаю, что это очень абсурдный / основной вопрос, но все же:

class m
{
public:
   void f(int ***);
  /***/
}
void m::f(int ***a = NULL)
{
  /***/
}

Вызов функции f (а также любой функции, которая имеет значения по умолчанию для всех аргументов) не принимает 0 аргументов. Зачем? Как мне тогда отформатировать декларацию?

Ответы [ 3 ]

13 голосов
/ 16 января 2010

Это прекрасно работает, если определение функции находится в заголовочном файле. Правило состоит в том, что тот, кто вызывает функцию, должен «видеть» значение по умолчанию.

Итак, я думаю, у вас есть определение функции в отдельном исходном файле. Предполагая, что это так, просто поместите значение по умолчанию в объявлении функции (в классе):

class m
{
public:
   void f(int *** = 0);
  /***/
};

Вам также необходимо удалить значение по умолчанию из определения функции, поскольку вы можете определить значение по умолчанию только в одном месте (даже если само значение одинаково).

2 голосов
/ 16 января 2010

Значения по умолчанию в C ++ являются синтаксическим сахаром; компилятор по существу вставляет аргумент для вас на месте вызова. Это означает, что компилятору необходимо знать значение по умолчанию, поэтому оно должно быть предоставлено объявлением функции.

Это также означает, что если у вас есть наследование и виртуальные методы, значения по умолчанию используются из статического типа (то есть, какого типа компилятор считает объект), а не из типа времени выполнения. Например:

class Base
{
public:
    virtual ~Base() { }

    virtual std::string foo(std::string s = "b") { return "Base:" + s; }
};

class Derived
: public Base
{
public:
   virtual std::string foo(std::string s = "d") { return "Derived:" + s; }
};

int main(void)
{
   Derived d;
   Base& b = d;
   std::cout << b.foo() << std::endl;
   return 0;
}

напечатает Derived:b, а не Derived:d.

2 голосов
/ 16 января 2010

Это будет работать:

class m
{
public:
   void f(int ***a = NULL);
};

void m::f(int ***a)
{
}
...