OccamaRazor
@OccamaRazor

Невозможно преобразовать double в void*?

Реализация на чистом "С"

Пытаюсь сделать функцию которая принимает данные любого типа и печатает их (пока только int, char*, double), проблема с double : выдаёт ошибку о невозможности преобразования 13.3 в тип указателя. Как правильно передать значение в макрос а затем в функцию чтобы сохранить значение? Пока только идея преобразовывать в строку а затем обратно в double, какой подход будет самым умным и оптимальным?

#include <stdio.h>
#include <stdlib.h>

#define puts(x) _Generic((x),                     \
  char*:       _puts((void*) x, "str"),           \
  int:         _puts((void*) x, "int"),           \
  double:      _puts(*(void**)x, "float")          \
)


void _puts(void* d, const char* type)
{
  if (type == "int"){
    printf("%d", d);
  } else if (type == "float"){
    printf("%lf", d);
  } else {
    puts(d);
  }
}


int main(void) {
  convert("String");
  convert(1230);
  convert(13.3);

	return 0;
}
  • Вопрос задан
  • 576 просмотров
Пригласить эксперта
Ответы на вопрос 3
devalone
@devalone
̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻̻
template <typename T>
void print(const T& obj) {
    std::cout << obj;
}
Ответ написан
Комментировать
@MiiNiPaa
Чем вам не нравится printf("%s", d) вместо puts?

Кстати, сравнивать строковые литералы, как это делаете вы нельзя. "float" == "float" вполне может равнятся false.

И так как у вас в тегах С++: почему макрос, а не шаблон со static if, tag dispatch или просто перегруженные функции?
Ответ написан
@res2001
Developer, ex-admin
Где функция convert()?
Про сравнение строк вам уже ответили.
Но у вас еще в printf полная фигня. Вы ей передаете void* при этом в шаблоне у вас int и double. Нужно делать преобразование и разыменование:
if (type == "int"){
    printf("%d", *((int*)d));
  } else if (type == "float"){
    printf("%lf", *((double*)d));

Ну и вместо строк "int, "float", ... лучше использовать какие-либо целочисленные константы - их то можно сравнивать напрямую.
На Си вашу затею так же красиво как в плюсах не реализовать. Для каждого типа данных нужна своя функция convert с уникальным именем (converti(int), convertd(double), ...).
В макросе нет возможности автоматически узнать какой тип данных ему передан, поэтому ваш код не откомпилируется.
Необходимо явно указывать какую функцию для вывода вызывать (или явно указывать какой тип данных в нее передается).
Например имеем набор функций для вывода соответствующего типа данных:
void putsi(int);
void putsd(double);
void putss(const char *);

#define PUTS(t, val)   puts ## t(val)

int main()
{
   PUTS(i, 123);
   PUTS(d, 3.14);
   PUTS(s, "hello world!");
  return 0;
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы