Но, увы, оно не пашет. Пишет, "не могу вывести аргументы для Args". Я, конечно, понимаю, можно вынести формат первым аргументом, но вот очень не хочется. Есть ли выход?
W>Но, увы, оно не пашет. Пишет, "не могу вывести аргументы для Args". Я, конечно, понимаю, можно вынести формат первым аргументом, но вот очень не хочется. Есть ли выход?
Здравствуйте, Went, Вы писали:
W>... W>Но, увы, оно не пашет. Пишет, "не могу вывести аргументы для Args". Я, конечно, понимаю, можно вынести формат первым аргументом, но вот очень не хочется. Есть ли выход?
Я бы не стал ставить format последним аргументом хотя бы из предпосылки, что так проще запутаться.
Здравствуйте, watchmaker, Вы писали: W>Есть костыль.
Отличный костыль. Достаточно крпкий
В финале получилось вот что:
namespace print_impl {
inline const TextFormat& get_format(const TextFormat& format)
{
// Нашли формат в хвосте - прекрасноreturn format;
}
inline const TextFormat& get_format()
{
// Если формат не нашли - это дефолтный форматreturn text_format::normal;
}
template<typename T, typename... Args>
const TextFormat& get_format(const T& other, const Args&... rest)
{
// Если после формата есть еще что-то - это явная ошибка
static_assert(!std::is_same<TextFormat, T>::value, "text format is not last print argument");
// Иначе ищем формат у хвостаreturn get_format(rest...);
}
} // print_implinline String print(const TextFormat& format)
{
// Печатаем ничто не важно каким форматомreturn"";
}
template<typename T, typename... Args>
String print(const T& a0, const Args&... args)
{
// Печатаем много чего, формат добываем из последнего аргумента, если такой естьreturn print(a0, print_impl::get_format(a0, args...)) + print(args...);
}
Всяческие перегрузки функции print на два аргумента (что пишем и опционально формат) реализованы отдельно.
Здравствуйте, ArtDenis, Вы писали: AD>Я бы не стал ставить format последним аргументом хотя бы из предпосылки, что так проще запутаться.
Он опционален. Да и вообще, так уж сделано
Здравствуйте, Went, Вы писали:
W>Здравствуйте, Molchalnik, Вы писали: M>>попробуй для начала задать окончание рекурсии. W>А разве верхняя функция ей не является?
Здравствуйте, Molchalnik, Вы писали:
M>Здравствуйте, Went, Вы писали: M>думаю, концом рекурсии была бы функция с шаблонными параметрами template<typename T, typename Last>
Зачем? Если учесть, что в рассматриваемом примере аргумент format обязателен (нет значения по умолчанию, нет перегрузки без оного), то добавление такой функции создаст возможность допустить ошибку, закончив функцию не-интом.
Или в этой функции подразумевается static_assert(false)?
Здравствуйте, Went, Вы писали:
W>Здравствуйте, Molchalnik, Вы писали:
M>>Здравствуйте, Went, Вы писали: M>>думаю, концом рекурсии была бы функция с шаблонными параметрами template<typename T, typename Last> W>Зачем? Если учесть, что в рассматриваемом примере аргумент format обязателен (нет значения по умолчанию, нет перегрузки без оного), то добавление такой функции создаст возможность допустить ошибку, закончив функцию не-интом. W>Или в этой функции подразумевается static_assert(false)?
Блин. Ты спрашиваешь других или пытаешься убедить себя в своей правоте? Вот решение твоей задачи. Без всяких там костылей вроде статик ассертов
template<typename T> void print_internal(T a) {
(void)a;
}
template<typename T>
void print(T a, int format)
{
// Тут мы выводим а в консоль в формате format.
(void)a;
(void)format;
printf("\nDone!!!");
}
template<typename T, typename... Args>
void print(T a0, Args... args)
{
print_internal(a0);
print(args...);
}
struct StType {
int x;
long y;
};
int main(int argc, char *argv[])
{
StType st_x;
print("f", 3);
print("f", (long)5, 3);
print("f",8,st_x,(long)3, (int)5);
//print("f",8,st_x,(long)3, st_x); //если раскомментировать, то эта строка даст ошибку
}
вывод программы:
Done!!!
Done!!!
Done!!!
Ты НЕ сделал окончание рекурсии грамотно — и поэтому у тебя или не работает, или костыли в виде ассертов.
Здесь ЕСТЬ правильное окончание рекурсии — и здесь и работает, и вызвать функцию print с последним аргументом, отличным от int НЕВОЗМОЖНО без ошибок компиляции.
И, что важно, использовать подсказку ты не захотел. Мне нужно было потратить своё время, сделать этот пример самому, для того, чтобы ты стал квалифицированнее и зарабатывал больше. Потому что ты повёл себя излишне самоуверенно и не подумал над ответом. Когда ты станешь получать больше, ты будешь присылать мне роялти?
P.s. Кстати, если задать второе окончание рекурсии,
void print() {};
, то этому коду станет наплевать на последний аргумент, пройдёт любой. А пока окончание рекурсии существует только для последнего аргумента типа int, поэтому и работает только для int'а последнего, на этом и основано решение.