LINUX.ORG.RU

C++: функция с переменным числом аргументов

 


0

1

Пытаюсь создать функцию с переменным числом аргументов типобезопасным способом с помощью шаблонов.

#include <iostream>
#include <concepts>

template<typename First, typename... Rest> 
requires std::is_convertible_v<First, const std::string&> && (std::is_convertible_v<Rest, const std::string&> && ...)
void f(First &&first, Rest&&... rest) {
    f(first);
    f(std::forward(rest)...);
}

template<>
void f(const std::string &first) {
    std::cout << first << std::endl;
}

int main() {
    f("foo", "bar");
}

Однако компилятор игнорирует специализацию f и жалуется об отсутствии версии f без аргументов.

Перемещено hobbit из general

★★★★★

Я не знаю что ты делаешь, но я бы делал так.

жалуется об отсутствии версии f без аргументов.

Можешь запретить && (sizeof...(Rest) > 0)

#include <iostream>    // fo std::cout
// #include <concepts> // not needed
#include <string>      // for std::string
#include <utility>     // for std::forward
#include <type_traits> // for std::is_convertible_v

void f(const std::string& first) {
    std::cout << first << std::endl;
}

template<typename First, typename... Rest>
    requires std::is_convertible_v<First, const std::string&> 
      && (std::is_convertible_v<Rest, const std::string&> && ...)
      && (sizeof...(Rest) > 0)
void f(First&& first, Rest&&... rest) {
    f(first);
    f(std::forward<Rest>(rest)...);
}

int main() {
    f("foo", "bar");
}

https://gcc.godbolt.org/z/8bhn9MT3q

fsb4000 ★★★★★
()
Последнее исправление: fsb4000 (всего исправлений: 1)
Ответ на: комментарий от fsb4000

"foo" и "bar" это не std::string, поэтому шаблон с void f(First&& first, Rest&&... rest) больше подходит для вызова чем void f(const std::string& first).

Если бы были строки, то тогда бы выбралось всё как ты хочешь.

https://gcc.godbolt.org/z/8vdGq5chW

fsb4000 ★★★★★
()