Могу ли я иметь пакеты параметров const? - PullRequest
0 голосов
/ 21 января 2019

Хорошо, так что

Работая над простой системой ведения журналов, я получил интересную проблему.Я подумал, что было бы неплохо иметь возможность написать что-то вроде:

Log(Info, "Result: {}", value);

Чтобы получить такой результат, как

Result: 45

(здесь используется стиль форматирования fmt.)

Итак, я настроил функцию так:

template <typename ...args_t>
void Log(LogLevel Level, const char* Message, args_t&&... Args)

Работает отлично, проблем нет.Тем не менее, я придерживаюсь мнения, что если аргумент не изменяется функцией, он должен быть помечен как const (для оптимизации и как примечание для программиста), поэтому я попытался это сделать:

template <typename ...args_t>
void Log(const LogLevel Level, const char* Message, const args_t&&... Args)

Это продолжает давать мне ошибки, VS2017 дает мне

error C2665: 'Log': none of the 4 overloads could convert all the argument types

Я просто делаю это неправильно?Не следует ли мне беспокоиться о константности пакета параметров?Есть лучший способ сделать это?Этот бизнес, связанный с упаковкой параметров, иногда трудно обернуть мне голову.

(я потратил около 3 часов на изучение этого вопроса и не смог найти какую-либо соответствующую информацию о переполнении стека или интернете в целом, пожалуйста, простите меня, если этоуже где-то ответили.)

1 Ответ

0 голосов
/ 21 января 2019

Вы используете ссылку переадресации, когда вы действительно хотите использовать константную ссылку.

Замените args_t&& на const args_t&.

Ссылка пересылки объявляется с использованием того же синтаксисав качестве ссылки rvalue, с двойным & (т. е. &&).Что отличает одно от другого, так это то, появляется ли он в выводимом контексте : ссылки на пересылку выводятся, а ссылки на rvalue - нет.Другими словами, если компилятор использует аргументы вашей функции для определения параметров шаблона (например, в вашем случае), это ссылка на пересылку.В противном случае это ссылка на rvalue.

В вашем случае ссылка на const предпочтительнее, поскольку вы явно намереваетесь не изменять аргументы.Поскольку вы никогда не захотите принимать параметры по ссылке, отличной от const, вам не нужен совершенный пересылка, при использовании ссылки const вы получите проверяемую компилятором неизменность, а также возможность принимать значения (например, литералы).и т. д.).

...