Как определить, был ли параметр функции автоматически установлен в значение по умолчанию или был задан явно в C ++?

Я совершенно уверен, что это невозможно, но если что-то существует (возможно, с помощью макросов, предоставляемых компилятором), это было бы очень полезно для меня, поэтому я публикую это здесь. Предположим, у меня есть функция:

void func( int param1, bool param2=false){ ... }

param2 здесь задано значение по умолчанию. Есть ли механизм, чтобы определить, если param2 было явно установлено его значение по умолчанию false или оно прошло автоматически? Другими словами, изнутри функции funcМожно ли отличить следующие два звонка? Я использую компилятор Microsoft Visual C ++.

func(1, false);

а также

func(1);

4

Решение

Вы не можете отличить способ, которым вы спрашиваете, но вы можете сделать это:

void func(int param1, boost::optional<bool> param2=boost::none);

Затем вы можете проверить, есть ли param2 или нет (у него есть собственный оператор bool). Если он установлен, это означает, что он был передан. Сайты вызовов будут выглядеть так же, как и раньше, потому что необязательный может быть неявно создан из его типа значения.

2

Другие решения

Значение false является одинаковым независимо от того, установлен ли он по умолчанию или каким-либо другим механизмом (обратите внимание также, что параметры по умолчанию разрешаются во время компиляции, поэтому во время выполнения нет абсолютно никакого способа проверить, задан он или нет).

Вы можете написать две функции:

void func( int param1, bool param2 )
{
...
}

void func( int param1 )
{
... do things differently ...
func( param1, false );
}

(Может быть, вам нужно позвонить func( int ) от func (int, bool) вместо конечно).

Другим вариантом будет изменить ваш bool в некоторый пользовательский тип:

enum TriState { False, True, Unknown };

void func( int param1, TriState parma2 = Unknown )
{
...
}

Конечно, теперь вам нужно будет изменить все true в True, а также false в Falseи у вас могут быть проблемы, потому что if (someTriStateVar) верно для Unknown тоже.

1

http://coliru.stacked-crooked.com/a/f6bcee72b5c957d1

#include <iostream>

struct CheckDefault {
CheckDefault() : value(false), param_default(true) {}
CheckDefault(bool b) : value(b), param_default(false) {}
bool value;
bool param_default;
};

void func(int param1, CheckDefault s = CheckDefault()) {
if (s.param_default)
std::cout << "with default, ";
else
std::cout << "not default, ";
if (s.value)
std::cout << "and value is true" << std::endl;
else
std::cout << "and value is false" << std::endl;
}

int main() {
func(5);
func(5, false);
func(5, true);
}

Выход:

$ ./test2
with default, and value is false
not default, and value is false
not default, and value is true

Там должно быть больше информации, чем просто один bool, поэтому мы вводим второй bool и оборачиваем их вместе в новый тип. Вызов функции с явным bool запускает конструктор CheckDefault, который принимает bool в качестве единственного аргумента. Этот конструктор также инициализирует param_default в false. Вызов без явного bool запускает конструктор, который не принимает аргументов. Он инициализирует записи s.value со значением false, но устанавливает для параметра param_default значение true, чтобы отметить, что это было по умолчанию.

Отредактировано, чтобы показать входные данные для истинного и ложного.

Предложение других использовать перегрузку является хорошим. Чтобы быть более точным, вот как это будет выглядеть:

void func(int param1) {
bool b = false;
// do stuff ...
}

void func(int param1, bool b) {
// do stuff ...
}
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector