Перейти к содержанию
    

Плавный переход C -> C++ под МК

В 19.06.2024 в 09:31, EdgeAligned сказал:

А может лучше

а как внутри func() узнать размер arr[]? Можно void func(int *arr, int size), а можно вообще void func(void *arr, int size, MyType type_) - получится пуре СИ ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 минут назад, arhiv6 сказал:

В С99 есть Compound Literals, которые в gcc и clang поддерживаются и для С++ :
 

func((int[]){1, 2, 3});

Я понимаю, что они есть. Но выглядят они максимально криво в коде - мне не нравится, поэтому от Сишных вариантов я ушел.

Идеально, когда можно записать просто func(1, 2, 3), а в теле функции автоматом считается количество переданных аргументов и сами аргументы. Без всяких монструозных оберток и тонны вспомогательного "мусора".

Класс initializer_list хорош тем, что нативно имеет компоненты begin и size, поэтому проблема красивой передачи массивов в функцию решена. Откусить бы еще фигурные скобки в вызове и было бы вовсе идеально.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нашел на стековерфлоу среди интересных тем кусочек кода, который позволяет вывести тип N-го аргумента в переменном списке аргументов вариативного шаблона

template<std::size_t N, typename T, typename... types>
struct get_Nth_type
{
    using type = typename get_Nth_type<N - 1, types...>::type;
};

template<typename T, typename... types>
struct get_Nth_type<0, T, types...>
{
    using type = T;
};

template<std::size_t N, typename... Args>
using get = typename get_Nth_type<N, Args...>::type;


Соответственно, вызов get<N, Args...> выдаст тип N-го аргумента из списка. Например

template <typename ...Args>
void func(Args... args) {
  get<0, Args...>;
}

int main() {
  func(1);   // в вызове get выше вернет int
  func('c'); // в вызове get выше вернет char
}


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

template <typename ...Args, typename std::enable_if<std::is_same<get<0, Args...>, int>::value, int>::type = 0>
void func(Args... args) {
  static_assert(sizeof...(Args) <= 3, "Too many arguments!");
}


Это я методом проб и ошибок написал. Вроде даже работает))

Теперь к первому вопросу - как работает эта конструкция get<> определения типа?

Правильно ли я понимаю, что здесь специализируется get_Nth_type для N == 0, а остальной "фокус" заключается в "сдвиге" пачки параметров и рекурсивном раскручивании get_Nth_type, пока N не станет равным 0?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть ли какой-то чисто практический пример, а не академический, когда указатели на методы или данные класса действительно лаконично решают задачу?

Как-то не совсем очевиден профит от их наличия в языке, такое чувство, что их добавили по приколу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И еще момент. Почему-то во всех учебниках пишут про то, что в файле заголовка должна быть предоставлена реализация шаблона функции.

Разве это прям 'should be'? Я что, не могу написать в заголовочнике

template<typename T>
void func(T val);

а в одном из .cpp-файлов реализовать нужный набор перегруженных функций, например,

void func(int i) {
}

void func(double d) {
}

?

P.S. Хех, нельзя.

Цитата

Error: L6218E: Undefined symbol void func<double>(double) (referred from main.o).
Error: L6218E: Undefined symbol void func<int>(int) (referred from main.o).


Т.е. видимо для шаблонных функций компилятор создает несколько "другие" имена, нежели для обычных перегруженных функций.

P.S. А вот так уже работает

template<>
void func<int>(int i) {
}

template<>
void func<double>(double d) {
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 minutes ago, Arlleex said:

а в одном из .cpp-файлов реализовать нужный набор перегруженных функций,

и это работает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2. Это давний и неисправленный косяк языка С++. Любой метод можно вынести в .cpp файл. Но как только дело касается ошаблонивания, тут всё - приехали, ничего не получается, не компилируется. Как мне кажется, это косяк еще из инлайн-функций Си.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, EdgeAligned сказал:

2. Это давний и неисправленный косяк языка С++. Любой метод можно вынести в .cpp файл. Но как только дело касается ошаблонивания, тут всё - приехали, ничего не получается, не компилируется. Как мне кажется, это косяк еще из инлайн-функций Си.

Ну, механизмы "почему так происходит", вроде понятны (теперь и мне).

Видимо, иначе особо и никак по-другому.

Я хотел, чтобы в заголовочнике был только "интерфейс" для быстрого охвата глазами. А в реализации уже потроха - туда смотреть не надо. При обмазывании шаблонами в таком случае красиво не получается - приходится всем показывать потроха в заголовке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По-другому никак. Я сам недели две бился над этим вопросом, искал ответы, пробовал повсякому - бесполезно. Вероятно, этот косяк так и останется, пока в какой-нить C++37 версии его не заметят и к С++45 быть может поправят 🙂

Касательно указателей на методы. В С++ во время его становления много чего перекочевало из его прародителя Си. Да так и осталось болтаться. Я ж уже давно подметил, С++ - просто свалка всего и вся, забитый хламом чердак, который никто не разбирает, а только надстраивают еще и еще этажи сверху.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, x893 сказал:

А вот на C# никаких проблем нет.

Ну а на шарпе под микрокомпудахтерынтроллеры писать можно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 minutes ago, Arlleex said:

Ну а на шарпе под микрокомпудахтерынтроллеры писать можно?

А кто запрещает ? Конечно можно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...