LINUX.ORG.RU

Чтобы компилятор различал стандартный тип и «кастомный» (typedef)

 , , ,


0

1

Всем привет

Есть шаблонная функция (fn в примере внизу), которая действует по-разному в зависимости от типа аргумента. Есть кастомный тип (TNew в примере внизу), который является синонимом стандартного типа unsigned char. Мне нужно чтобы функция действовала по-разному в случаях, когда ей передается стандартный тип или кастомный. C++ же воспринимает кастомный тип как синоним стандартного, и не дает специфицировать функцию.

В общем, проще на примере.

Код внизу не компилируется, так как компилятор трактует
void fn(const unsigned char &arg)
void fn(const TNew &arg)
как одно и то же. А нужно, чтобы он различал эти функции/типы.

Такое возможно?

#include <iostream>
#include <iomanip>

typedef unsigned char TNew;

template <class T>
void fn(const T &arg)
{
  std::cout << "generic" << std::endl;
}

template <>
void fn(const unsigned char &arg)
{
  std::cout << "unsigned char" << std::endl;
}

template <>
void fn(const TNew &arg)
{
  std::cout << "TNew" << std::endl;
}


int main()
{
  int a;
  unsigned char b;
  TNew c;

  fn(a);
  fn(b);
  fn(c);

  return 0;
}

★★★★★

Ответ на: комментарий от DELIRIUM

Что класс? Написать километр кода для эмуляции unsigned char?

anonymous ()

Ты хочешь, чтобы компилятор различал, когда в качестве параметра шаблону передается псевдоним типа? На то он и псевдоним, чтобы быть для компилятора равнозначным. Ты бы лучше объяснил, зачем тебе это надо, потому что пока что это выглядит бессмысленно.

m0rph ★★★★★ ()
Ответ на: комментарий от anonymous

Вы вопрос вообще читали, капитаны фиговы?

anonymous ()
Ответ на: комментарий от m0rph

Ты бы лучше объяснил, зачем тебе это надо, потому что пока что это выглядит бессмысленно.

Потому что есть TModifier, который представляет собой модификаторы клавиш Ctrl, Alt, Shift и т. п.; в нем каждый бит что-то значит. См man keymaps, искать по «modifier». Сейчас он unsigned char.

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

Kroz ★★★★★ ()
Ответ на: комментарий от DELIRIUM

Такое возможно?

class

Наверное придется...

Kroz ★★★★★ ()
Ответ на: комментарий от m0rph

Например ты получаешь градусы цельсия, фаренгейта и кельвина в функцию, а возвращаешь или запоминаешь кельвины. Как только кресты фейлятся в чем-то тривиально-практическом, адепты начинают шланговать или выкатывать костыли, юзать которые самим им не позволит совесть и «чувство прекрасного». Обожаю эти моменты :3

anonymous ()
Ответ на: комментарий от Kroz

Так заверни в свой тип... Тебе нужно что-то в духе newtype из haskell'я?

Можно один раз написать универсальную обертку на C++.

anonymous ()

А почему enum нельзя сделать?

E ★★★ ()
Ответ на: комментарий от anonymous

Так заверни в свой тип... Тебе нужно что-то в духе newtype из haskell'я?

Так я и думал, что typedef - это новый тип. Оказалось просто alias.

Теперь вот через class переделываю...

Kroz ★★★★★ ()

Такое возможно?

Да:

enum TNew : unsigned char {};
anonymous ()
Ответ на: комментарий от anonymous

Да:
enum TNew : unsigned char {};

Это то же самое, что и class. c=5; не получится сделать.

Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

Это то же самое, что и class. c=5; не получится сделать.

Как раз с class получится - достаточно конструктор добавить. А тут, да, надо явно будет писать c = TNew( 5 ). Ну так ж ты новый тип хочешь.

anonymous ()
Ответ на: комментарий от anonymous

Как раз с class получится - достаточно конструктор добавить. А тут, да, надо явно будет писать c = TNew( 5 ). Ну так ж ты новый тип хочешь.

Получается!
Спасибо!

Kroz ★★★★★ ()
Ответ на: комментарий от anonymous

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

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

Как только кресты фейлятся в чем-то тривиально-практическом, адепты начинают шланговать или выкатывать костыли, юзать которые самим им не позволит совесть и «чувство прекрасного». Обожаю эти моменты :3

Кресты постоянно фейлятся в чем-то, потому что комитет занимается чем угодно, только не повышением удобства разработчика. Вот и появляются горы костылей, которые реализуют базовые вещи: замена RTTI, делегаты и прочие.

m0rph ★★★★★ ()
Ответ на: комментарий от Kroz

Потому что есть TModifier, который представляет собой модификаторы клавиш Ctrl, Alt, Shift и т. п.; в нем каждый бит что-то значит. См man keymaps, искать по «modifier». Сейчас он unsigned char.

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

Тогда действительно требуется создание нового типа. Можно сделать например битовое поле - даже нагляднее будет работа с ним.

m0rph ★★★★★ ()
Ответ на: комментарий от Kroz

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

Походу это не задача логгера, а того, кто этому логгеру передает данные.

andreyu ★★★★★ ()
Ответ на: комментарий от anonymous

адепты начинают шланговать или выкатывать костыли, юзать которые самим им не позволит совесть и «чувство прекрасного».

Просто из любопытства: можно пример, где эта ситуация элегантное решается? В плюсах, конечно, нет возможности легко и удобно вводить новые типы из существующих. Но ведь для новых типов всё равно пришлось бы реализовывать методы и т.д.

DarkEld3r ★★★★★ ()
Ответ на: комментарий от andreyu

Походу это не задача логгера, а того, кто этому логгеру передает данные.

И ты мне предлагаешь помнить детальный тип каждой переменной и писать что-то вида TNewToString, а если ошибусь - получить ерунду на выходе? Нет уж. Лучше уж я немного потрачу времени, но упрощу себе жизнь в дальнейшем, а главное - уберегусь от man-made ошибок.

Кстати, уже свой код передал - таки нашел такой вот баг.

Kroz ★★★★★ ()
Ответ на: комментарий от Kroz

И ты мне предлагаешь помнить детальный тип каждой переменной и писать что-то вида TNewToString

Нет, это задача форматера, а не логгера. Это две независимые сущности.

andreyu ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.