Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.02.2013, 15:36   #31
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от _Bers Посмотреть сообщение
void (*)(void) - так объявляется тип данных "указатель на функцию".
разве нельзя просто void*, без void(*)(void)?

Цитата:
Сообщение от _Bers Посмотреть сообщение
Данный указатель можно нацелить на свободную функцию, которая ничего не возвращает, и не принимает аргументов. Например вот на такую: void Bar(){}
у меня порой впечатление что вы думаете я совсем не понимаю программирование)) знаю ведь что void это "ничего"

Цитата:
Сообщение от _Bers Посмотреть сообщение
На языке с++ можно получать адрес твоих функций и запускать их по указателю, а не по имени.

Пример:

http://liveworkspace.org/code/2sz7PZ$6
в примере есть такая строка:
Код:
typedef int (*Func)(const char* text);
это что то вроде прототипа, он может принимать указатель на любую функцию что возвращает int и принимает константный указатель на char, так? если да, то таким способом мне надо сделать так чтобы программа вывела мне где функторы, а где нет, верно? а сам typedef делает синонимы каким то записям, и тип данных int теперь может принимать параметры через ().
в примере был создан указатель:
Func func;
потом говорим на какой адрес указывает указатель:
func = &Foo;
и обычный вызов
int test = func(параметры);

Цитата:
Сообщение от _Bers Посмотреть сообщение
const int val4 = is_callable<Functor, int>::value;
Будет равен 1, только если у функтора есть operator()(int){}
Но так как в примере в функтора оператор ничего не принимает, то выражение должно стать равным нулю.
тогда всё просто, но в записи <Functor, int> как любому шаблону мы просто указываем какие типы данных они будут использовать, в данном примере int вообще не используется, будет он или нет, что бы там не стояло всё равно ведь должен быть 1, или я не прав?
_SOKOL_ вне форума Ответить с цитированием
Старый 04.02.2013, 16:16   #32
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

наверное не смогу сделать этот механизм
_SOKOL_ вне форума Ответить с цитированием
Старый 04.02.2013, 21:59   #33
Perchik71
С++, Delphi
Форумчанин
 
Аватар для Perchik71
 
Регистрация: 24.11.2012
Сообщений: 495
По умолчанию

Наблюдая тихо за всем этим, мне Вас стало жаль, вас быстро посадили.
Я бы не стал этого делать. Не каждому от этого ощущения хорошо.
Совершенству нет. Пределу нет. Это язык С++. Написать в С++ можно по разному любую задачу. Этим он и интересен и по сей день на плову.
Многие языки пытаются его дублировать.
Если помог, тут весы есть , Вам не сложно, а мне приятно.
Perchik71 вне форума Ответить с цитированием
Старый 04.02.2013, 23:20   #34
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Поможем разобраться) Я покажу кое-что попроще, а именно, как проверить, что переданный тип является классом (или структурой, что в C++ почти то же самое).

Нам пригодится такая штука, как SFINAE: substitution failure is not an error (ошибка подстановки - не ошибка, грубо говоря). Когда мы вызываем функцию, и у нее есть несколько шаблонных перегрузок, тестируются все из них, и если для какой-то просто не удалось вывести сигнатуру функции, то вариант просто отметается. Пример:

Код:
class Test
{
  typedef int SomeType;
};

template <typename T>
void f (T::SomeType x) { }

template <typename T>
void f (T x) { }

int main ( )
{
  f<Test>(10);
/*
   первый вариант функции подходит - у типа Test внутри есть тип SomeType, и это int, как и ожидалось
   второй вариант не подходит - мы передаем в функцию int, который не умеет конвертироваться в Test
*/
  f<int>(10);
/*
   первый вариант не подходит - у типа int нет внутри типа SomeType
   второй вариант, очевидно, подходит
*/
}
Как мы будем использовать это правило? Для классов можно определить указатели на члены, этим мы и воспользуемся. Мы сделаем у функции фиктивный параметр типа int T::*, по умолчанию равный 0 (и не важно, есть ли у типа T члены типа int, указатель все равно можно объявить). Второй вариант функции будет принимать (...) - эллипсис выбирается в худшем случае, если не подошло ничто другое.
Нам нужно будет как-нибудь узнать, какой из вариантов функции выбрал компилятор. Мы это сделаем по возвращаемому значению функции. А именно, два варианта функции будут возвращать типы разного размера, а в результате мы просто проверим размер. Нам поможет одно замечательное свойство оператора sizeof (как и оператора decltype, появившегося в C++11) - он не вычисляет выражение внутри, только его тип.

Код:
template <typename T>
class is_class
{
private:
  typedef char small;
  struct big { small fake[2]; }; // тип, гарантированно больший, чем тип small

  template <typename H>
  static small check (int H::* p) { } // H - класс, указатель на член смог быть объявлен

  template <typename H>
  static big check (...) { } // если верхний вариант не подошел
public:
  statin const bool value = (sizeof(check<T>(0)) == sizeof(small));
};
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 05.02.2013, 07:18   #35
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

оказывается я ещё не окончил курс)
по программе уже должны были вчера экзамен сдавать, а нет, учили последовательные контейнеры, узнал прок контейнер vector
может ещё дойду до этой темы и сделаю всё таки тест))
_SOKOL_ вне форума Ответить с цитированием
Старый 05.02.2013, 11:17   #36
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Если Вы и про vector не знали...
Без обид, тут не Ваша вина, и не курса, просто язык такой, но Вам еще учиться и учиться. Собственно, всем, кто на нем пишет, еще учиться и учиться) Практикуйтесь, практикуйтесь, читайте статьи, практикуйтесь. На пути Вам могут встретиться другие языки, которые, на мой взгляд, в разы проще в изучении, и Вам придется решать, чего Вы хотите. В общем, перед Вами безграничный мир, так сказать)
Форматируйте код, будьте людьми.
Granus вне форума Ответить с цитированием
Старый 05.02.2013, 15:43   #37
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,577
По умолчанию

Granus
Цитата:
statin const bool value = (sizeof(check<T>(0)) == sizeof(small));
опечатка
а так прикольно, да

Похожий или такой же изворот я вроде бы у Саттера видел (со small и big), а может и не у него.

Этот пример я бы так переписал:
Код:
struct is_class {
  template<typename T>
  static bool check(int T::*) { return true; }
  template<typename T>
  static bool check(...) { return false; } 
};
посмотри пожалсто опытным глазом, скажи, это чем-то хуже?
------добавил
однако, использовать чуть менее удобнее )

Последний раз редактировалось rrrFer; 05.02.2013 в 16:15.
rrrFer вне форума Ответить с цитированием
Старый 05.02.2013, 16:08   #38
_SOKOL_
Пользователь
 
Регистрация: 02.02.2013
Сообщений: 44
По умолчанию

Цитата:
Сообщение от Granus Посмотреть сообщение
Если Вы и про vector не знали...
Без обид, тут не Ваша вина, и не курса, просто язык такой, но Вам еще учиться и учиться. Собственно, всем, кто на нем пишет, еще учиться и учиться) Практикуйтесь, практикуйтесь, читайте статьи, практикуйтесь. На пути Вам могут встретиться другие языки, которые, на мой взгляд, в разы проще в изучении, и Вам придется решать, чего Вы хотите. В общем, перед Вами безграничный мир, так сказать)
было б из за чего обижаться
я понимаю что С++ гибкий, но как Вы сказал, мне набираться опыта надо, иначе толку от того что знаю
тут на форуме проще набраться опыта
_SOKOL_ вне форума Ответить с цитированием
Старый 05.02.2013, 23:07   #39
Granus
С++
Форумчанин
 
Аватар для Granus
 
Регистрация: 22.09.2008
Сообщений: 791
По умолчанию

Цитата:
посмотри пожалсто опытным глазом, скажи, это чем-то хуже?
Вообще говоря, суть записи результата в статическую константу была в том, чтобы во время компиляции где-нибудь использовать это выражение. Функция же - это функция, её, если формально, нужно вызывать, чтобы получить значение. Но в С++11 появилась возможность указать, что значение функции может быть вычислено на этапе компиляции - перед ней нужно написать constexpr. Тогда, видимо, Ваш вариант намного лучше, чем использование трюка с sizeof. Результат все-таки удобнее записать в статическую константу, или, как советовал _Bers, в enum.

Кстати, _Bers, я тут подумал насчет этого. Нормальные компиляторы же сами удаляют константы, если никто не пытается взять их адрес или сделать еще что-нибудь, подразумевающее их существование в рантайме. Поэтому мы вроде как ничего не теряем, только слегка повышаем читабельность и понимание.
Форматируйте код, будьте людьми.

Последний раз редактировалось Granus; 05.02.2013 в 23:10.
Granus вне форума Ответить с цитированием
Старый 05.02.2013, 23:43   #40
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от Granus Посмотреть сообщение
Кстати, _Bers, я тут подумал насчет этого. Нормальные компиляторы же сами удаляют константы, если никто не пытается взять их адрес или сделать еще что-нибудь, подразумевающее их существование в рантайме. Поэтому мы вроде как ничего не теряем, только слегка повышаем читабельность и понимание.
Ключевое слово "если". Если никто не попытается - тогда да. Если попытается - тогда нет.

Мне енумы нравятся тем, что они как бы сообщают читателю: "это не член данных. Это просто значение времени компиляции"

А если это статик, то я уже призадумаюсь.

Известно, что адрес статического члена гарантированно уникален.И если взять этот адрес, то вы получите некое уникальное число.
Которое в свою очередь, может выступать в качестве идентификатора объекта, или его класса.

Или такой вариант: в декларацию класса загоняется статическая безымянная (но имеющая константное имя) структура. В эту структуру можно чего угодно дополнительно воткнуть. Так изготавливают метаданные на плюсах. Всякие контракты запихиваются.

Это может быть дело вкуса, но если я встречаю статическую константу, то я задумываюсь, зачем она нужна. Потому что в особенности в контексте мета-программирования там столько разных трюков бывает.

А енумы.. они простые. С ними дофига не сделаешь) Поэтому, мне они читабельнее видятся)
_Bers вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
с чего начиНАТЬ С/С++!!!! dk118 Помощь студентам 0 05.12.2012 01:22
С чего начинать leonidsm Свободное общение 4 06.10.2012 19:37
Какой язык лучше всего выбрать после завершения изучения языка Паскаль. VektorAB Помощь студентам 4 09.07.2010 07:16
С чего начинать? Shadol Свободное общение 6 24.11.2009 11:46
С++ ЧЕГО НАЧИНАТЬ !!! geniy Общие вопросы C/C++ 12 03.09.2007 10:50