необязательный постоянный аргумент псевдонима с постоянным аргументом - PullRequest
0 голосов
/ 16 января 2020

Как мы должны кодировать аргумент псевдонима, который не должен быть постоянным, с его аргументом по умолчанию, который должен быть постоянным, так как он не может ссылаться? 1004 * g cc дал

ошибка: невозможно связать неконстантную ссылку lvalue типа 'Bar &' с rvalue типа 'Bar'

Как решить - с понятным объяснением - что это за вид?

1 Ответ

3 голосов
/ 16 января 2020

Причина, по которой вы получаете эту ошибку, заключается в том, что, как вы обнаружили, ссылка не const должна привязываться к lvalue: то есть она должна привязываться к объекту с именем. Временный не будет привязан к ссылке не-const: только к const Bar& или Bar&&, ни к одному из которых вы не хотите.

Это оставляет нам несколько вариантов.

Моим личным фаворитом было бы вообще не использовать аргументы по умолчанию, а вместо этого предоставлять перегрузку:

int fooBar(int board, Bar& bar) {
  // ...
}

int fooBar(int board) {
  // to save code duplication you can call in fooBar
  Bar b{1};
  return fooBar(board, b);
}

На мой взгляд, это самый простой и наиболее последовательный вариант.

Другие возможности включают :

  • создание глобала, единственная цель которого состоит в том, чтобы быть аргументом по умолчанию (гадость и мешает многопоточности):
    inline Bar default_bar;
    int fooBar(int board, Bar& bar = default_bar) {
      // ...
    }
    
  • , используя вместо этого указатель, с оговоркой, которую вы должен проверить, предоставили ли они аргумент или нет:
    int fooBar(int board, Bar* bar = nullptr) {
      // ..., but make sure to test bar!
    }
    
  • или иным образом, используя std::optional<std::reference_wrapper<Bar>> или какой-то подобный тип.
...