Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
Kastaneda
Форумчанин
Эксперт С++
4262 / 2794 / 219
Регистрация: 12.12.2009
Сообщений: 7,122
Записей в блоге: 1
Завершенные тесты: 1
#1

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

29.12.2015, 07:33. Просмотров 394. Ответов 9
Метки нет (Все метки)

Привет!

Хочу как-то регистрировать все ф-ции, объявляемые в файле, например есть вот это

C++
1
2
3
std::string f1() { return "asdf1"; }
std::string f2() { return "asdf2"; }
std::string f3() { return "asdf3"; }
хотелось бы в конце файла иметь список
C++
1
{f1(), f2(), f3()}
Если точнее, то хочу использовать это так
C++
1
2
3
4
std::vector<std::string> registered_values()
{
    return { f1(), f2(), f3() };
}
Пока тело registered_values() прихоится руками поддерживать, вот хочется автоматизировать.
Я плохо умею обращаться с шаблонными фишками С++11, поэтому даже не уверен, что такое возможно. Понятно, что каждая f1, f2, ... будет структурой с оператором (), которая будет наследовать что-то, где будет вся магия. Может кто-то сможет это сделать?
Вопрос скорее любопытства ради, но если получится, то вставлю в проект
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.12.2015, 07:33     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
Посмотрите здесь:

C++ Compile-time алгоритмы. сборник
C++ Что такое compile-time алгоритмы и для чего они нужны?
C++ Не могу разобраться с заданием "Создайте класс Time с конструкторами Time(), Time( int hour)......"
list. Cоздать список из результатов(с массивами), а потом просмотреть весь список C++
C++ Ошибка C2552: non-aggregates cannot be initialized with initializer list
C++ Compile - time алгоритмы
Создать список целых чисел. Создать новый список, записав в него отрицательные элементы C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
hoggy
6010 / 2450 / 437
Регистрация: 15.11.2014
Сообщений: 5,424
Завершенные тесты: 1
29.12.2015, 22:40     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #2
Цитата Сообщение от Kastaneda Посмотреть сообщение
Пока тело registered_values() прихоится руками поддерживать, вот хочется автоматизировать.
смысли автоматизировать?
вам в любом случае придется указать имя функции,
которую нужно будет пинать.

и сделать это можно только в ручную.

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

все равно вбивать придется вручную.
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
29.12.2015, 23:13     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #3
Kastaneda, в общем, вот такая вот наркомания:
Кликните здесь для просмотра всего текста

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
117
118
119
120
#include <iostream>
#include <cstdint>
#include <vector>
#include <algorithm>
 
constexpr uint32_t ct_hash_suffix(char c, size_t seed)
{
    return static_cast<uint32_t>(c) + uint32_t(0x9e3779b9) + (seed << 6) + (seed >> 2);
}
 
uint32_t hash_value(std::string const & str)
{
    uint32_t seed = 0;
    for(char c : str)
    {
        seed ^= ct_hash_suffix(c, seed);
    }
    return seed;
}
 
constexpr uint32_t ct_hash(char const * str, uint32_t seed = 0)
{
    return *str ? ct_hash(str + 1, seed ^ ct_hash_suffix(*str, seed)) : seed;
}
 
template <uint32_t File, typename F>
class FunctionStorage
{
    template <typename FS>
    struct ResultOf;
 
    template <typename R, typename ...A>
    struct ResultOf<R(A...)>
    {
        using type = R;
    };
 
    using RetType = typename ResultOf<F>::type;
 
    struct Caller
    {
        RetType operator()(F f) const
        {
            return f();
        }
    };
 
public:
    static FunctionStorage & instance()
    {
        static FunctionStorage inst;
        return inst;
    }
 
    F * add(F * func)
    {
        m_funcs.push_back(func);
        return func;
    }
 
    F * operator[](size_t idx)
    {
        return m_funcs[idx];
    }
 
    std::vector<RetType> callAll() const
    {
        std::vector<RetType> ret(m_funcs.size());
        std::transform(m_funcs.begin(), m_funcs.end(), ret.begin(), Caller());
        return ret;
    }
 
private:
    std::vector<F *> m_funcs;
};
 
template <uint32_t File, typename FuncType>
class FunctionRegister
{
public:
    FunctionRegister(FuncType * f)
        : m_func(FunctionStorage<File, FuncType>::instance().add(f))
    { }
 
    FuncType * operator~() const
    { return m_func; }
 
private:
    FuncType * m_func;
};
 
#define REGISTERED_VALUES() \
    FunctionStorage<ct_hash(__FILE__), std::string()>::instance().callAll()
 
#define FUNCTION_DECL(F) \
    std::string(*F)() = ~(FunctionRegister<ct_hash(__FILE__), std::string()>)[]
 
 
/* Функции определяем так: */
FUNCTION_DECL(a)() -> std::string
{
    return "a";
};
FUNCTION_DECL(b)() -> std::string
{
    return "b";
};
 
int main()
{
   /* в зависимости от места вызова будет давать разные результаты
       например, для файла с функциями a.cpp будет один список, для файла b.cpp - другой.
       можно добавить еще один вариант, который принимает имя файла в качестве параметра
       тогда можно будет запрашивать списки, задавая нужный файл
   */
    auto v = REGISTERED_VALUES();
 
    for(auto & c : v)
        std::cout << c << std::endl;
}
http://rextester.com/QTPEI24794
Ни в коем случае не законченное решение, а скорее эксперимент. Но продолжать мне лень, но есть пара мыслей.
Что здесь плохо:
1) Хэш времени компиляции ненадежен. Можно заменить на полноценные compile-time строки в качестве уникального тега файла, но код станет более сложным и пример перестанет быть демонстрационным. В любом случае, если интересно, то могу поделиться своими наработками в этой области.
2) Даже со строками вместо хешей, будут коллизии в общем случае. Т.к. файлы в проекте теоретически могут называться одинаково. Я считаю, что на общий случай распространить решение не получится.
3) Функции на самом деле не функции, а указатели на функции, следовательно могут возникнуть проблемы при необходимости использовании внешнего связывания (как вариант, можно воспользоваться сишным приемом "extern указатель на функцию", для использования в других единицах трансляции).
4) std::vector внутри хранилища зарегистрированных функций. Пока что не вижу разумных вариантов этого избежать.
5) Невозможность обобщить решение на любые функции: с любым количеством параметров и типов возвращаемого значения. Для этого скорее всего придется что-то сильно менять, текущий вариант этого не позволит в полной мере.

В любом случае, баловаться таким в реальных проектах я бы не советовал.
Это же ужас что. Кто потом это будет поддерживать?!
Однако, возможно какие-то идеи окажутся полезными и ты решишь написать свой вариант на базе них, который будет более соответствовать задаче (более узкоспециализированным) и окажется более безопасным и простым из-за этого.
Kastaneda
Форумчанин
Эксперт С++
4262 / 2794 / 219
Регистрация: 12.12.2009
Сообщений: 7,122
Записей в блоге: 1
Завершенные тесты: 1
30.12.2015, 06:09  [ТС]     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #4
Цитата Сообщение от hoggy Посмотреть сообщение
я хочу сказать, нет разницы:
в ручную вбить очередное имя в теле функции,
или вручную вбить это же имя где нибудь в параметре шаблона.
Есть разница. Вот что я имею ввиду - хочу добавить новую ф-цию, добавляю
C++
1
2
3
4
std::string f123()
{
    return "asdf123";
}
при этом я (или другой программист) должен не забыть добавить ее в другую ф-цию.
C++
1
2
3
4
std::vector<std::string> registered_values()
{
    return { f1(), f2(), f3(), ..., f123() };
}
Т.е. добавление чего-то одного требует правки в двух местах. Это не есть гуд, очевидно, что кто-нибудь когда-нибудь забудет.

DrOffset, спасибо, чуть позже поразбираюсь.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
30.12.2015, 10:19     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #5
DrOffset, Шикарно.
Цитата Сообщение от DrOffset Посмотреть сообщение
1) Хэш времени компиляции ненадежен. Можно заменить на полноценные compile-time строки в качестве уникального тега файла, но код станет более сложным и пример перестанет быть демонстрационным. В любом случае, если интересно, то могу поделиться своими наработками в этой области.
Интересно, если есть возможность, было бы очень интересно увидеть.
Kastaneda
Форумчанин
Эксперт С++
4262 / 2794 / 219
Регистрация: 12.12.2009
Сообщений: 7,122
Записей в блоге: 1
Завершенные тесты: 1
30.12.2015, 10:40  [ТС]     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #6
Да, посмотрел, круто получилось!
Сам еще тоже немного посидел на этим делом, хотел что-то принципиально другое сделать. Сначал с бустовским препроцессором полчаса просидел, может и можно сделать, но за полчаса не осилил, потом еще с полчаса хотел сам что-то сваять через шаблоны.
В итоге потратил час рабочего времени на задачу, которая даже не нужна (без нее все работает), вернулся обратно к работе).
DrOffset
6840 / 4051 / 924
Регистрация: 30.01.2014
Сообщений: 6,855
31.12.2015, 01:23     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #7
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от 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
Kastaneda
Форумчанин
Эксперт С++
4262 / 2794 / 219
Регистрация: 12.12.2009
Сообщений: 7,122
Записей в блоге: 1
Завершенные тесты: 1
31.12.2015, 05:59  [ТС]     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #8
DrOffset, спасибо, разберу на досуге.

Не по теме:

Вчера тему перенесли в "С++ для экспертов", сегодня обратно. Постучись в группу, должны принять.

ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
31.12.2015, 11:32     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time #9
Kastaneda,

Не по теме:

Угу, я попросил перенести обратно.


DrOffset, Это шикарно. Не думал что ты сильно увлекаешься template метапрограммированием. Спасибо что поделился.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.12.2015, 13:59     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
Еще ссылки по теме:

Создать динамический шаблонный класс односвязный список - List C++
Ошибка: error: cannot convert '<brace-enclosed initializer list>' to 'int C++
C++ Compile-time и run-time методы и функции
C++ Создать класс Элемент списка (Node), а затем класс Список (List)
C++ Выделение памяти объёмом, известном в compile-time

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
DrOffset
31.12.2015, 13:59     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
  #10

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Постучись в группу, должны принять.
Вообще, я сознательно туда не иду


Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение
Не думал что ты сильно увлекаешься template метапрограммированием.
Нельзя сказать, что сильно увлекаюсь. По работе (как собственно и С++11/14) не использую, только вот в таких вот задачках.

Yandex
Объявления
31.12.2015, 13:59     Создать список ф-ций определяемых в файле (а-ля initializer list) в compile time
Ответ Создать тему
Опции темы

Текущее время: 17:25. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru