Сообщение CTC без препроцссора - помогите довести до ума! от 13.04.2017 21:32
Изменено 13.04.2017 21:33 rg45
Re: CTC без препроцссора - помогите довести до ума!
Это не готовая реализация CTC, а только прототип, упрощенный до предела так, чтобы видна была идея.
Достоинства:
Недостатки:
http://rextester.com/ZSP64839
Пример использования:
Достоинства:
- не используются никакие константы препроцессора (__LINE__, __COUNTER__ и пр);
не используется специализации шаблона основного класса счетчика, что допускает его применение не только в пространстве имен, но и в теле классов (до C++17 спещиализация вложенных классов должна была выполняться только в обрамляющем пространстве имен);
возможность одновременного использования множества независимых счетчиков;
автоматический инкремент при каждом обращении к счетчику.
Недостатки:
- Ограничение максимального значения счетчика, довольно низкое. Над этим можно пока не заморачиваться. У меня есть кое-какие соображения как можно расширить этот барьер;
ГЛАВНАЯ ПРОБЛЕМА: привести счетчик в соответствие требованиям стандарта! Сейчас эта реализация работает только на msvc. Как я ни бился, мне так и не удалось заставить это заработать под gcc. Причина ясна — дружественная функция не появляется в окружающем пространстве имен.
http://rextester.com/ZSP64839
constexpr size_t CTC_MAX = 498;
template <size_t i>
struct Index : Index<i - 1> { static constexpr size_t value = i; };
template <> struct Index<0> { static constexpr size_t value = 0; };
Index<0> generate(...);
#define CREATE_CTC(name) template <typename T = decltype(generate(Index<CTC_MAX>()))> struct name : T { friend Index<T::value + 1> generate(T); };
#define GET_CTC(name) name<>::value
Пример использования:
CREATE_CTC(ctc1)
enum class Foo
{
zero = GET_CTC(ctc1),
one = GET_CTC(ctc1),
two = GET_CTC(ctc1),
three = GET_CTC(ctc1),
four = GET_CTC(ctc1),
five = GET_CTC(ctc1),
};
CTC без препроцссора - помогите довести до ума!
Это не готовая реализация CTC, а только прототип, упрощенный до предела так, чтобы видна была идея.
Достоинства:
Недостатки:
http://rextester.com/ZSP64839
Пример использования:
Достоинства:
- не используются никакие константы препроцессора (__LINE__, __COUNTER__ и пр);
не используется специализации шаблона основного класса счетчика, что допускает его применение не только в пространстве имен, но и в теле классов (до C++17 спещиализация вложенных классов должна была выполняться только в обрамляющем пространстве имен);
возможность одновременного использования множества независимых счетчиков;
автоматический инкремент при каждом обращении к счетчику.
Недостатки:
- Ограничение максимального значения счетчика, довольно низкое. Над этим можно пока не заморачиваться. У меня есть кое-какие соображения как можно расширить этот барьер;
ГЛАВНАЯ ПРОБЛЕМА: привести счетчик в соответствие требованиям стандарта! Сейчас эта реализация работает только на msvc. Как я ни бился, мне так и не удалось заставить это заработать под gcc. Причина ясна — дружественная функция не появляется в окружающем пространстве имен.
http://rextester.com/ZSP64839
constexpr size_t CTC_MAX = 498;
template <size_t i>
struct Index : Index<i - 1> { static constexpr size_t value = i; };
template <> struct Index<0> { static constexpr size_t value = 0; };
Index<0> generate(...);
#define CREATE_CTC(name) template <typename T = decltype(generate(Index<CTC_MAX>()))> struct name : T { friend Index<T::value + 1> generate(T); };
#define GET_CTC(name) name<>::value
Пример использования:
CREATE_CTC(ctc1)
enum class Foo
{
zero = GET_CTC(ctc1),
one = GET_CTC(ctc1),
two = GET_CTC(ctc1),
three = GET_CTC(ctc1),
four = GET_CTC(ctc1),
five = GET_CTC(ctc1),
};