Как видите, я неправильно использую тип данных auto
в функции log()
. Но я думаю, что это демонстрирует то, что мне нужно. Я пытаюсь создать простую оболочку cout
и не знаю, как она будет выглядеть для любого типа данных.
void log(auto str = "DEFAULT LOG", bool b_endl = true)
{
std::cout << str; if (b_endl == true) { std::cout << std::endl; }
}
int main()
{
log("string");
log(3);
log(3.0);
return 0;
}
Если вы не склонны иметь аргумент по умолчанию на str
, я могу написать ответ. Если вам НУЖЕН этот дефолт, вам придется подождать кого-то гораздо более хитрого, чем я. Это или смириться с перегрузкой.
«Но я думаю, что это демонстрирует то, что мне нужно». -- Вы можете так подумать, но лучше описать желаемую функциональность словами (с кодом в качестве запасного варианта).
@JaMiT Это название;)
@user4581301 user4581301 Спасибо, я поищу шаблоны, потому что даже не знаю, что это такое!
Рад, что вы прокомментировали. Не осознавал, что каким-то образом превратил свой ответ в совершенно другой вопрос.
@user4581301 user4581301 Строка по умолчанию для str
не нужна для моих нужд.
@CodeN00b «Это название» — что конкретно означает «это» в этом контексте? Все, что я вижу в заголовке, — это краткое изложение вашей цели, а не функциональных требований. Хорошо иметь в заголовке просто краткое изложение (см. Как задать вопрос), но этого недостаточно для описания вашего функционала. Показательный пример: ваш заголовок не дает указания на то, почему первый параметр должен иметь значение по умолчанию. Детали имеют значение, а резюме по своей природе не содержат подробностей.
Я не уверен, что вы ищете. Код, который вы опубликовали , компилируется и выдает именно тот результат, который я ожидал . Вы спрашиваете о вызове без аргументов?
Разве не здорово, когда со временем компиляторы становятся все более способными? Майлз использует самую последнюю версию стандарта языка C++. И я подумал, что дерзко добавляю заметку о концепциях C++20.
@ user4581301 auto
параметры работают и с C++20.
@Майлз, сукин сын. Так и есть. Мне следовало прочитать аннотации более внимательно.
Чем больше текста описывается, что вы пытаетесь сделать, тем больше вероятность того, что ответы, которые вы получите, помогут кому-то еще в будущем. Меньше текста == меньше возможностей для поиска.
Примечание. Код Asker будет работать, начиная с C++20. Поскольку это не так, ответ написан, главным образом, при условии, что C++20 недоступен.
Используйте шаблон для разрешения типа аргумента. Вы теряете возможность вызова функции без параметров и только с аргументами по умолчанию, не можете вывести аргумент шаблона без аргумента, но это легко исправить с помощью перегрузки, если возможность вызова log()
является жестким требованием.
#include <iostream>
#include <string>
template <class TYPE>
void log(TYPE str, bool b_endl = true)
{
std::cout << str;
if (b_endl == true)
{
std::cout << std::endl;
}
}
//for the totally parameter-less version
void log()
{
std::cout << "DEFAULT LOG" << std::endl;
}
int main()
{
log("string");
log(3);
log(3.0);
log();
return 0;
}
Пример вывода:
string
3
3
DEFAULT LOG
Примечание. Вы по-прежнему будете получать ошибки, если передадите аргумент, который невозможно разрешить (например: log({1,2,3,4});
) или аргумент, который нельзя напечатать с помощью <<
(например: log(std::vector<int>());
). Начиная с C++20, вы можете получить немного более понятную ошибку. сообщение, если аргумент шаблона не может быть передан в потоковом режиме с помощью concept
:
#include <iostream>
#include <string>
#include <vector>
template<class TYPE>
concept outstreamable = requires(std::ostream & out, TYPE b) {
out << b;
};
template <class TYPE> requires outstreamable<TYPE>
void log(TYPE str, bool b_endl = true)
{
std::cout << str;
if (b_endl == true)
{
std::cout << std::endl;
}
}
//for the totally parameter-less version
void log()
{
std::cout << "DEFAULT LOG" << std::endl;
}
int main()
{
log("string");
log(3);
log(3.0);
log(std::vector<int>());
return 0;
}
Эта версия позволяет вам узнать, что требование TYPE
быть outstreamable
было нарушено, вместо того, чтобы выплевывать страницу за страницей шаблоны, которые были опробованы, но не смогли соответствовать.
Спасибо за подробный пример!
@CodeN00b Обратите внимание на точку зрения Майлза в комментариях к вопросу о том, что если вы обновите свой компилятор и создадите его на C++20 или выше, то, что вы пробовали, будет работать.
Небольшая придирка: log()
вместо этого следует брать параметр TYPE
по ссылке на константу: void log(const TYPE &str, ...)
и то же самое с outstreamable
#include <iostream>
// General template to handle multiple arguments
template<typename... Args>
void log(Args... args)
{
(std::cout << ... << args) << std::endl;
}
// Specialization or overload for no arguments, providing a default log
void log() {
std::cout << "DEFAULT LOG" << std::endl;
}
int main()
{
log("Logging: ", 1, " and ", 2.5); // Handles multiple types
log("Another log with a single parameter");
log(); // Uses the default log
return 0;
}
Шаблоны (
template <class TYPE> void log(TYPE str = "DEFAULT LOG", bool b_endl = true)
) здесь ваши друзья, но учтите, что не все могут принимать строку в качестве аргумента по умолчанию и имеют перегрузку<<
.