Передача литеральной строки в качестве параметра шаблона не подходит

Я работаю над проектом С++, и я только что определил функцию, как показано ниже:

template<typename... Args>
void func(Args&&... args) {}

Затем назовите это так:

func("abc"); // char[4]?
func("de");  // char[3]?

Мой вопрос: выведет ли компилятор две независимые функции, одну для char[4], а другую для char[3]? Если я вызову много func с const char*, как указано выше, компилятор сгенерирует много независимых функций?

Это глупо? Должен ли я избегать этого?

На самом деле, func("abc") и func(std::string("abc")); для меня абсолютно одно и то же.

Так должен ли я вызывать эту функцию как func(std::string("abc")); и func(std::string("de"));, чтобы компилятор сгенерировал только одну функцию как void func(const std::string&);

Кстати, мой проект разработан на С++ 14.

Может быть полезно попробовать ваш код в www.godbolt.org, чтобы увидеть, что различные компиляторы будут производить с различными флагами сборки.

François Andrieux 10.05.2022 16:11

Да, функция будет сгенерирована для каждого размера строкового литерала. Если вы используете std::string, вы рискуете динамическим размещением, так что это компромисс между временем компиляции/исполняемым пространством и стоимостью времени выполнения. Если большинство ваших строк короткие, например, менее 15 символов, вы выиграете от единого входа, и это делает компромисс еще более тонким. Лично, если вы не заметите, что это становится проблемой, я бы придерживался того, что у вас есть сейчас.

NathanOliver 10.05.2022 16:12

Я полагаю, это также зависит от того, что вы ожидаете от этой функции. Всегда ли это работает со строками? Работает ли он с массивоподобными объектами? И т. д. При использовании шаблонов я лично всегда следую мантре определения максимально ограниченного возможного шаблона, чтобы было более предсказуемо то, что генерирует компилятор. Шаблоны Variadic обычно используются только в крайнем случае (или в качестве «переадресатора»), поскольку при необходимости распаковать пакет параметров шаблона вниз по линии действительно неудобно.

Jacob Faib 10.05.2022 16:13

Это зависит от многого. Если функция короткая, она, вероятно, все равно будет встроена, так что вы ничего не потеряете. В противном случае вы должны спросить себя в реальном коде, сколько жестко закодированных строк вы собираетесь использовать? Также, возможно, стоит рассмотреть интерфейс в стиле STL с использованием указателей на начальные и конечные символы или использование std::string_view (и, возможно, std::span).

Galik 10.05.2022 16:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
54
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

My question is if the compiler will deduce two independent functions, one is for char[4] and the other is for char[3]?

Будет.

If I call many func with const char* as above, the compiler will generate many independent functions?

Вы не звоните func с const char*. Если бы вы вызвали func только с const char*, то был бы только один экземпляр шаблона функции.

Вы вызываете функцию с помощью const char[4] и const char[3], которые вызывают отдельные экземпляры. Будет создан экземпляр для каждого уникального набора аргументов шаблона.

Is this stupid? Should I avoid this?

Зависит от варианта использования. Во многих случаях оптимизатор просто расширяет все встроенные вызовы, и экземпляры не оставляют никаких следов их теоретического существования в сгенерированной сборке.

Другие вопросы по теме