Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
Другие темы раздела
C++ AllocHook https://www.cyberforum.ru/ cpp/ thread1615167.html
Помнится в какой-то теме были задачи одного из собеседований озвучены. Из-за давности той темы отдельно создал новую. Заинтересовала меня тогда одна задача. Определить сколько памяти израсходовал map...
C++ Перезаписывать index.html каждый раз, когда меняется количество файлов в директории https://www.cyberforum.ru/ cpp/ thread1624542.html
нужно сделать так, чтобы каждый раз когда меняется количество файлов в каталоге C:\\, программа перезаписывала файл index.html #include <stdio.h> #include <iostream> #include <windows.h>... Поставь слежение за папкой (ReadDirectoryChangesW), и при добавлении/удалении файла перезаписывай index.html
C++ Создать и подключить библиотеку в Dev-C++ Помогите пожалуйста. Необходимо создать библиотеку и exe файл. При запуске exe файла ввести 2 значения (a=число1, b=число2). Эти числа должны передаться библиотеке (dll) там сложиться и вернуться... https://www.cyberforum.ru/ cpp/ thread1617603.html Как достать кириллические символы из char* C++
Добрый день. Использую библиотеку, которая возвращает строку в char*. Если создавать std::wstring из этой строки, то кириллица отображается как знаки вопросов. Помогите достать из буфера char*... По коду символа сопоставляйте.
C++ Информация о железе https://www.cyberforum.ru/ cpp/ thread1618027.html
Здравствуйте форумчане Очень нужно узнать информацию о: HDD(разделы, размер каждого раздела, сколько занято места) CPU(температура, загрузку каждого ядра) процессы(как в диспетчера задач) службы... https://msdn.microsoft.com/en-us/library/ms724423(v=vs.85).aspx Копать сюда примерно.
C++ Контроль звуковых потоков Всем привет,не знал,где разместить тему,т.к вроде тема не для новичков,но на эксперта не тянет. Проблема следующая,необходимо получить доступ к различным потокам выхода с возможностью их... Вы хотите обнять необъятное :). Если хотите контролить микрофон - это одна тема, веб-камеру-другая тема, инет - еще одна тема. Все это можно собрать в один проект, но учитывая ваши знания, это будет... https://www.cyberforum.ru/ cpp/ thread1626276.html
C++ Перемещение фигуры Реализовать отображение на экране геометрической фигуры с возможностью перемещать ее с помощью клавиш(стрелки) и изменение цвета фигуры "+". win32 приложение заводишь глобальные dx dy в WM_PAINT запихиваешь отрисовку нужной фигуры c подставленными dx dy дальше отлавливаешь нажатия кнопок и в них засовываешь код увеличения dx dy. Изи... https://www.cyberforum.ru/ cpp/ thread1618220.html C++ Сделать валидатор Здравствуйте, уважаемые) На форуме только поселился, если кто-то может помочь, то буду очень благодарен) К сожалению, я не очень силен(надеюсь, что пока), в регулярных выражениях, да и с qt мало... но я пошел самым, на мой взгляд, эффективным, а именно - регулярки. Прочитай мою подпись :)строку вида "45км 5" принимает за верную Потому что (?м?), это значит, что единицы измерения может и не... https://www.cyberforum.ru/ cpp/ thread1622460.html
C++ Вычисление количества знаков после запятой Написал функцию определяющую, что у числа менее 4 знаков после запятой. Помогите оптимизировать. bool rac(double a) { int c(0); a -= int(a); while (a - int(a) && c < 4) { ... https://www.cyberforum.ru/ cpp/ thread1617858.html Ошибка сегментирования при компиляции C++
Когда компилирую через g++ компилируется, при запуске выдает ошибку сегментирования, а при компиляции через NetBeans IDE выдает две ошибки, на скринах показал. Задача: Разработать две программы –... а при компиляции через NetBeans IDE выдает две ошибки, на скринах показал. Ты похоже оба файла в один проект загнал, комплятор говорит, что у тебя 2 main'а в коде. при запуске выдает ошибку...
C++ Когнитивные карты Доброго времени суток. Если кто сталкивался помогите решить. Нужно запрогать когнитивную карту, но не знаю с какой стороны подойти. Буду признателен за любую помощь Заранее спасибо! https://www.cyberforum.ru/ cpp/ thread1619960.html C++ Не могу заставить g++ не инициализировать локальную переменную нулем https://www.cyberforum.ru/ cpp/ thread1616331.html
Привет! Есть такой код (из серии "что будет напечатано на экран") #include <iostream> using namespace std; int x = 1; namespace A { int x = 2; clang: http://rextester.com/LPWKA67741 http://clang.llvm.org/compatibility.html Non-initialization of __block variables In the following example code, the x variable is used before it is...
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
31.12.2015, 01:23 0

Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time - C++ - Ответ 8565606

31.12.2015, 01:23. Показов 1972. Ответов 9
Метки (Все метки)

Лучший ответ Сообщение было отмечено Kastaneda как решение

Решение

Цитата Сообщение от ForEveR Посмотреть сообщение
было бы очень интересно увидеть.
Публиковал относительно недавно на другом российском форуме. Вариация на тему compile-time механизма перевода приложения.
С++11 (в С++14 будет чуть поменьше кода)
ct_string.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef CT_STRING_H_INCLUDED
#define CT_STRING_H_INCLUDED
 
namespace ct
{
 
template <char ...Chars>
struct string
{
    enum { length = sizeof...(Chars) - 1 };
 
    static char const value[];
};
 
template <char ...Chars>
char const string<Chars...>::value[] = { Chars... };
 
} // ct
 
#endif // CT_STRING_H_INCLUDED

ct_indices_utils.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef CT_INDICES_UTILS_H_INCLUDED
#define CT_INDICES_UTILS_H_INCLUDED
 
#include <cstddef>
 
namespace ct
{
 
template <size_t ...I>
struct indices
{ };
 
template <size_t Max, size_t ...Indices>
struct make_indices
    : make_indices<Max - 1, Max - 1, Indices...>
{ };
 
template <size_t ...Indices>
struct make_indices<0, Indices...>
    : indices<Indices...>
{
    using type = indices<Indices...>;
};
 
} // ct
 
#endif // CT_INDICES_UTILS_H_INCLUDED

ct_string_utils.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef CT_STRING_UTILS_H_INCLUDED
#define CT_STRING_UTILS_H_INCLUDED
 
#include "ct_string.h"
#include "ct_indices_utils.h"
 
namespace ct
{
 
template <typename Str, typename I>
struct string_gen;
 
template <typename Str, size_t ...I>
struct string_gen<Str, ::ct::indices<I...>>
    : ::ct::string<Str{}.chars[I]...>
{ };
 
template <typename Str, size_t Len>
struct make_string
    : string_gen<Str, typename ::ct::make_indices<Len>::type>
{ };
 
} // ct
 
#endif // CT_STRING_UTILS_H_INCLUDED

translator.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#ifndef TRANSLATOR_H_INCLUDED
#define TRANSLATOR_H_INCLUDED
 
#include "ct_string.h"
#include "ct_indices_utils.h"
#include "ct_string_utils.h"
 
class Translator
{
public:
    enum { LangMax = 5 };
 
    struct Holder
    {
        char const * m_strings[LangMax];
    };
 
private:
    template <typename Value>
    struct Storage : Value, Holder
    {
        template <size_t ...I>
        Storage(Translator & self, ct::indices<I...>)
            : Holder{ { ((void)I, Value::value)... } }
        { }
 
        explicit Storage(Translator & self)
            : Storage(self, ct::make_indices<LangMax> {})
        { }
    };
 
    template <char ...Chars>
    Holder * addString(ct::string<Chars...> const &)
    {
        static Storage<ct::string<Chars...>> s(*this);
        return &s;
    }
 
public:
    static Translator & instance()
    {
        static Translator inst;
        return inst;
    }
 
    template <typename Original, typename Translated>
    void addTranslation(size_t lang)
    {
        Holder * h = this->addString(Original{});
        h->m_strings[lang] = Translated::value;
    }
    template <typename Original>
    char const * addString()
    {
        Holder * h = this->addString(Original{});
        return h->m_strings[m_lang];
    }
 
    static void setLang(size_t lang)
    {
        instance().m_lang = lang;
    }
 
private:
    size_t m_lang = 0;
};
 
#define TR(str) []() \
    {                                                                   \
        struct StringType1 { const char * chars = (str); };             \
        using type1 = ::ct::make_string<StringType1, sizeof((str))>;    \
        return Translator::instance().addString<type1>();               \
    }()
 
#define SETUP_TR(lang, orig, trans) []() \
    {                                                                   \
        struct StringType1 { const char * chars = (orig);  };           \
        using type1 = ::ct::make_string<StringType1, sizeof((orig))>;   \
        struct StringType2 { const char * chars = (trans); };           \
        using type2 = ::ct::make_string<StringType2, sizeof((trans))>;  \
        Translator::instance().addTranslation<type1, type2>(lang);      \
        return true;                                                    \
    }()
 
#endif // TRANSLATOR_H_INCLUDED

Использование:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <cstdio>
 
#include "translator.h"
 
enum { RUS = 1 };
 
namespace {
bool f1 = SETUP_TR(RUS, "start", "старт");
bool f2 = SETUP_TR(RUS, "text", "текст");
}
 
int main()
{
    Translator::setLang(RUS);
 
    std::printf("%s\n", TR("start"));
    std::printf("%s\n", TR("start"));
    std::printf("%s\n", TR("text"));
}
http://rextester.com/WYUMS67445

Добавлено через 11 часов 16 минут
Kastaneda, в общем выдалась свободная минутка, и я слегка улучшил первоначальный код и избавился от некоторых проблем.
Нужен C++14, но можно и без него, просто мне уже не очень охота переделывать.
Итак, сперва чего удалось достичь:
1) Теперь нет глобальных переменных-указателей, вместо этого полноценные функции (хоть и шаблонные).
2) Вследствие этого теперь возможно поместить реализацию функций в заголовочный файл. Хитрость с явным инстанцированием частичной специализации, вместо применения полной специализации позволит избежать multiple definition.
3) Избавился от вектора в качестве хранилища. Теперь там связный список на статических объектах. Куча не используется до входа в main вообще.
4) Идентификация файла через compile-time строковый тег - коллизиям говорим "нет" . Кстати, проблемы одинаковых файлов не возникнет, по крайней мере на GCC и Clang, т.к. __FILE__ там включает полное имя, а не короткое.
5) В качестве регистрируемой функции можно использовать функцию с любой(!) сигнатурой. Будет создано по отдельному хранилищу на каждый тип. Предусмотрена возможность задать нужный тип для группового вызова.

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

ct_string_v1.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef CT_STRING_V1_H_INCLUDED
#define CT_STRING_V1_H_INCLUDED
 
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/config/limits.hpp>
 
template <char ...Chars>
struct string
{};
 
namespace detail
{
    template <typename Res, char ...Chars>
    struct trim_zeros_impl;
 
    template <char... N, char C, char ...Chars>
    struct trim_zeros_impl<string<N...>, C, Chars...>
        : std::conditional<C
            , trim_zeros_impl<string<N..., C>, Chars...>
            , trim_zeros_impl<string<N..., 0>> // force recursion end
          >::type
    { };
 
    template <char ...Chars>
    struct trim_zeros_impl<string<Chars...>>
    {
        using type = string<Chars...>;
    };
}
template <char ...Chars>
struct trim_zeros
    : detail::trim_zeros_impl<string<>, Chars...>
{ };
 
#define STRING_TO_CHARS_BY_ONE(Z, N, STR) \
        BOOST_PP_COMMA_IF(N) N >= sizeof(STR) ? '\0' : STR[N]
 
#define STRING_TO_CHARS(LEN, STR)  \
        BOOST_PP_REPEAT(LEN, STRING_TO_CHARS_BY_ONE, STR)
 
#define MAKE_CT_STRING(STR) trim_zeros<STRING_TO_CHARS(256, STR)>::type
 
#endif // CT_STRING_V1_H_INCLUDED

func_registry.h

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#ifndef FUNC_REGISTRY_H_INCLUDED
#define FUNC_REGISTRY_H_INCLUDED
 
#include <type_traits>
#include <utility>
 
#include <vector>
#include <cstddef>
 
#include "ct_string_v1.h"
/*----------------------------------------------------------------------------*/
template <typename File, typename FType>
struct FunctionReg
{
    explicit FunctionReg(FType f);
 
    FunctionReg * next;
    FType *       call;
};
/*----------------------------------------------------------------------------*/
template <typename File, typename F>
class FunctionStorage;
 
template <typename File, typename Ret, typename ...Args>
class FunctionStorage<File, Ret(Args...)>
{
    using FuncPtrType  = Ret(*)(Args...);
    using FuncRegistry = FunctionReg<File, Ret(Args...)>;
 
    FunctionStorage()
        : m_first(), m_last(), m_len()
    {}
public:
    static FunctionStorage & instance()
    {
        static FunctionStorage inst;
        return inst;
    }
    void append(FuncRegistry * reg)
    {
        if(m_first)
        {
            m_last->next = reg;
        }
        else
        {
            m_first = reg;
        }
        m_last = reg;
        ++m_len;
    }
    std::vector<Ret> callAll(Args && ...args)
    {
        std::vector<Ret> ret(m_len);
 
        FuncRegistry * reg = m_first;
        for(size_t i = 0; reg; reg = reg->next)
        {
            ret[i++] = reg->call(std::forward<Args>(args)...);
        }
        return ret;
    }
 
private:
    FuncRegistry * m_first;
    FuncRegistry * m_last;
    size_t         m_len;
};
/*----------------------------------------------------------------------------*/
template <typename File, typename FType>
FunctionReg<File, FType>::FunctionReg(FType f)
    : next(), call(f)
{
    FunctionStorage<File, FType>::instance().append(this);
}
/*----------------------------------------------------------------------------*/
template <typename FuncName, typename FileName>
struct FunctionEntry;
/*----------------------------------------------------------------------------*/
 
#define FUNCTION_DECL(FName, Body) \
template <typename FileName> \
struct FunctionEntry<MAKE_CT_STRING(#FName), FileName>                      \
{                                                                           \
    static auto FName Body;                                                 \
private:                                                                    \
    using  FuncReg = FunctionReg<FileName, decltype(FunctionEntry::FName)>; \
    static FuncReg reg;                                                     \
}; \
\
template class FunctionEntry<MAKE_CT_STRING(#FName), MAKE_CT_STRING(__FILE__)>; \
\
template <typename FileName>                                                  \
typename FunctionEntry<MAKE_CT_STRING(#FName), FileName>::FuncReg             \
            FunctionEntry<MAKE_CT_STRING(#FName), FileName>::reg(             \
                &FunctionEntry<MAKE_CT_STRING(#FName), FileName>::FName       \
            ); \
\
template <typename ...Args>          \
inline auto FName(Args && ...args)   \
{ return FunctionEntry<              \
            MAKE_CT_STRING(#FName)   \
          , MAKE_CT_STRING(__FILE__) \
         >::FName(std::forward<Args>(args)...); \
} \
\
template <typename FileName> \
auto FunctionEntry<MAKE_CT_STRING(#FName), FileName>::FName Body
 
#define CALL_ALL(Type, ...) \
    FunctionStorage<MAKE_CT_STRING(__FILE__), Type>::instance().callAll(__VA_ARGS__)
 
#define CALL_ALL_FROM(File, Type, ...) \
    FunctionStorage<MAKE_CT_STRING(File), Type>::instance().callAll(__VA_ARGS__)
 
#endif // FUNC_REGISTRY_H_INCLUDED

Использование:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <string>
#include <cstdio>
 
#include "func_registry.h"
 
FUNCTION_DECL(test1, (int a) -> std::string)
{
    return "test1!";
}
FUNCTION_DECL(test2, (int b) -> std::string)
{
    return "test2!";
}
FUNCTION_DECL(test3, (int c) -> std::string)
{
    return "test3!";
}
FUNCTION_DECL(test4, () -> int)
{
    return 42;
}
 
int main()
{
    auto v = CALL_ALL(std::string(int), 1);
    for(auto & c : v)
        std::printf("%s\n", c.c_str());
 
    auto l = CALL_ALL(int());
    for(auto & c : l)
        std::printf("%d\n", c);
}
Онлайн пример: http://rextester.com/QOF3281

Вернуться к обсуждению:
Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time C++
6
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
31.12.2015, 01:23
Готовые ответы и решения:

Compile-time и run-time методы и функции
Добрый день. Есть две функции, которые делают идентичную работу: template&lt;bool leftShift, typename T&gt; T byteShift(T data) { ...

Compile - time алгоритмы
мне итересно, с появлением constexpr надобность в шаблонных компиле-тайм алгоритмах полностью отпала?..)

Compile-time алгоритмы. сборник
всем привет. предлагаю в этой теме обсуждать/реализовывать/выкладывать compile-time алгоритмы. под CUT'ом. подсчет FNV1a-хеш суммы...

9
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
31.12.2015, 01:23
Помогаю со студенческими работами здесь

Const в delay.h: compile time integer constant
Есть такая библиотека, delay.h. В ней есть функция _delay_us(double __us): _delay_us(double __us) { double __tmp ; #if...

Выделение памяти объёмом, известном в compile-time
Правда ли, что, скажем new int Произойдёт существенно быстрее, чем int length = runtimeComputeLength(); // returns 1000 new int;

Ошибка C2552: non-aggregates cannot be initialized with initializer list
помогите пожалуйста: struct sAccInt { Account AccFrom; Account AccTo; sAccInt() : AccFrom(0L), AccTo(0L) ...

Ошибка compile-time constant для аргумента по умолчанию
Имеется два метода class MyFile { public static string ReadAll(string filename, Encoding enc = Encoding.UTF8) { ...

ASPX файлы и как отлавливать в них ошибки в compile time
Пришлось тут столкнуться с legacy, в котором оказалось много ошибок в ASPX (обращение к несуществующим полям классов, например). При этом...

0
Новые блоги и статьи
std::mutex в C++: Хитрости и тонкости использования
Wired 03.03.2025
В C++ ключевым инструментом для обеспечения корректной работы параллельных процессов выступает std::mutex – примитив синхронизации, появившийся в стандарте C++11. До его появления использовали. . .
std::span в C++: Производительно­сть и практическое использование
Wired 03.03.2025
Традиционная работа с указателями и массивами часто приводит к ошибкам и уязвимостям в безопасности. Именно поэтому в C++20 появился std::span - легковесная обертка, обеспечивающая безопасный. . .
std::span в C++: Константность и безопасность типов
Wired 03.03.2025
std::span - представитель семейства view-типов, появившийся в стандарте C++20. Этот компонент предоставляет легковесное и эффективное решение для работы с непрерывными последовательностями данных,. . .
std::span в C++: Subview и Slice
Wired 03.03.2025
std::span - невладеющий тип данных C++, который предоставляет гибкий интерфейс для работы с непрерывными последовательностями элементов. Этот тип существенно упрощает обработку массивов и. . .
std::span в C++: Доступ к элементам и итерирование
Wired 03.03.2025
Появление std::span в стандарте C++20 стало значительным шагом вперед, предоставив разработчикам средство для безопасного и производительного доступа к непрерывным последовательностям элементов. . . .
std::span в C++: Управление массивами данных без владения
Wired 03.03.2025
Новый класс std::span, появившийся в стандарте C++20, открывает возможности для оптимизации работы с последовательными наборами данных. По сути, это легковесная обертка, которая предоставляет доступ. . .
Неблокируемый стек в C++26: реализуем простой сборщик мусора
stackOverflow 02.03.2025
Многопоточные приложения требуют надежных и производительных структур данных, способных эффективно работать в условиях конкурентного доступа. Неблокируемые структуры данных представляют собой особый. . .
Шаблон REQ/REP в ZeroMQ: сверхбыстрый обмен сообщениями в C++ и Python
stackOverflow 02.03.2025
Построение высоконагруженных распределенных систем требует надежного и производительного механизма обмена сообщениями. ZeroMQ выделяется среди прочих решений своей невероятной скоростью работы и. . .
Нестандартные приемы работы с итераторами в C++
stackOverflow 02.03.2025
Итераторы - один из краеугольных камней C++, предоставляющий универсальный механизм обхода и манипуляции данными в контейнерах. Появившись как замена небезопасным указателям, они эволюционировали от. . .
Лексический анализ и регулярные выражения в C++26
stackOverflow 02.03.2025
Лексический анализ - ядро любого компилятора и инструмента обработки текста. Каждый программист сталкивается с задачами парсинга строк, обработки файлов конфигурации или анализа пользовательского. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru