Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++0x] функция генерация uid как constexpr 
V
    Опции темы
rudvil
Дата 29.4.2011, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 20.11.2009
Где: Latvia/Riga

Репутация: 2
Всего: 3



Реально ли функцию std::size_t uid() сделать как constexpr, чтобы приведенный ниже код заработал?
http://liveworkspace.org/code/a64a5b6a70e0...226de52e9393491
Код
#include <cstddef>
#include <iostream>

std::size_t uid() {
  static std::size_t id = 0;
  return ++id;
}

struct foo {
  static const std::size_t id1 = uid();
  static const std::size_t id2 = uid();
};

int main() {
  std::cout << foo::id1 << std::endl;
  std::cout << foo::id2 << std::endl;
  return 0;
}


Цитата(output)
source.cpp:10:38: error: 'std::size_t uid()' is not 'constexpr'
source.cpp:11:38: error: 'std::size_t uid()' is not 'constexpr'

Build finished with errors


Про enum'ы знаю, их можно не предлагать.
Пока что смог вот так извратиться, но все время писать эти макросы жутко не удобно
http://liveworkspace.org/code/957f17038912...2bcc6714c2fa5c8
Код
#include <cstddef>
#include <iostream>

#include <boost/preprocessor/slot/counter.hpp>

struct foo {
  static const std::size_t id1 = BOOST_PP_COUNTER;
#include BOOST_PP_UPDATE_COUNTER()
  static const std::size_t id2 = BOOST_PP_COUNTER;
};

int main() {
  std::cout << foo::id1 << std::endl;
  std::cout << foo::id2 << std::endl;
  std::cout << std::endl;
  return 0;
}


Цитата(output)
0
1

какие могут быть решения данной проблемы?
--------------------
xor
PM MAIL Skype   Вверх
mes
Дата 29.4.2011, 17:10 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(rudvil @  29.4.2011,  14:24 Найти цитируемый пост)
Реально ли функцию std::size_t uid() сделать как constexpr, чтобы приведенный ниже код заработал?

нет, constexpr функция не может иметь состояния.. 



--------------------
PM MAIL WWW   Вверх
rudvil
Дата 29.4.2011, 22:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 20.11.2009
Где: Latvia/Riga

Репутация: 2
Всего: 3



Цитата(mes @ 29.4.2011,  17:10)
Цитата(rudvil @  29.4.2011,  14:24 Найти цитируемый пост)
Реально ли функцию std::size_t uid() сделать как constexpr, чтобы приведенный ниже код заработал?

нет, constexpr функция не может иметь состояния..

Понятно, спасибо.
--------------------
xor
PM MAIL Skype   Вверх
boostcoder
Дата 29.4.2011, 22:09 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(rudvil @  29.4.2011,  15:24 Найти цитируемый пост)
все время писать эти макросы жутко не удобно

есть еще встроенный макрос __COUNTER__

PM WWW   Вверх
rudvil
Дата 29.4.2011, 23:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 155
Регистрация: 20.11.2009
Где: Latvia/Riga

Репутация: 2
Всего: 3



Цитата(boostcoder @ 29.4.2011,  22:09)
Цитата(rudvil @  29.4.2011,  15:24 Найти цитируемый пост)
все время писать эти макросы жутко не удобно

есть еще встроенный макрос __COUNTER__

Спасибо, кажется наилучшее решение.  smile 

Это сообщение отредактировал(а) rudvil - 29.4.2011, 23:58
--------------------
xor
PM MAIL Skype   Вверх
mes
Дата 30.4.2011, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



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






--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 30.4.2011, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  30.4.2011,  09:20 Найти цитируемый пост)
недостаток в повторении значений в разных единицах трансляции

если, к примеру, не нужны последовательные значения, то __COUNTER__ можно комбинировать с __LINE__
PM WWW   Вверх
mes
Дата 30.4.2011, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(boostcoder @  30.4.2011,  15:12 Найти цитируемый пост)
то __COUNTER__ можно комбинировать с __LINE__ 

а разве это гарантирует уникальность ?

Добавлено через 1 минуту и 52 секунды
к тому же может привести к проблеме, когда из за добавления одной незначащий строчки, появиться неожидано непредвиденное поведение smile



--------------------
PM MAIL WWW   Вверх
boostcoder
Дата 30.4.2011, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(mes @  30.4.2011,  16:18 Найти цитируемый пост)
а разве это гарантирует уникальность ?

нет, естественно smile

Добавлено @ 16:24
Цитата(mes @  30.4.2011,  16:18 Найти цитируемый пост)
из за добавления одной незначащий строчки, появиться неожидано непредвиденное поведение

это да.

я когда-то пытался закодить что-то вроде этого.. мне нужен был компайл-тайм typeid. но только чтоб он не имена типов возвращал, а целые в качестве ID`ов. ну и забросил. вроде как на тот момент это мне казалось невозможным... была идея пропатчить компилятор smile


Это сообщение отредактировал(а) boostcoder - 30.4.2011, 16:25
PM WWW   Вверх
borisbn
Дата 2.5.2011, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Прошу прощения, что спрашиваю в чужой теме, но вопрос IMHO близкий...
А можно как-нибудь проверить в compile-time уникальность констант, но не через switch. Есть такой код
Код

template< unsigned long long ID >
struct MyStruct {
    static const unsigned long long id = ID;
...
};
typedef MyStruct< 0x123456789L > SomeStruct1;
typedef MyStruct< 0x123456789L > SomeStruct2; // вот тут хотелось бы получить ошибку

Если ТС будет против - создам отдельную тему.
Спасибо


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 2.5.2011, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



borisbn, вроде как цели схожи: http://forum.vingrad.ru/forum/topic-319669.html

Добавлено через 1 минуту и 45 секунд
а вообще - нет, такое невозможно.
решение влоб - добавлять твои типы в некий mpl-контейнер с проверкой на предмет существования.
PM WWW   Вверх
mes
Дата 2.5.2011, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  2.5.2011,  11:54 Найти цитируемый пост)
typedef MyStruct< 0x123456789L > SomeStruct1;
typedef MyStruct< 0x123456789L > SomeStruct2; // вот тут хотелось бы получить ошибку

это _вдвойне_ невозможно, так как typedef не создает новый тип  smile 



--------------------
PM MAIL WWW   Вверх
borisbn
Дата 2.5.2011, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(boostcoder @  2.5.2011,  13:10 Найти цитируемый пост)
а вообще - нет, такое невозможно.

Цитата(mes @  2.5.2011,  14:37 Найти цитируемый пост)
это _вдвойне_ невозможно

_вдвойне_ жаль :(

Цитата(boostcoder @  2.5.2011,  13:10 Найти цитируемый пост)
решение влоб - добавлять твои типы в некий mpl-контейнер с проверкой на предмет существования.

не очень понял (читай - вообще не понял), т.к. с mpl-контейнерами не работал. Можешь показать пример ? И ещё вопрос, __COUNTER__ исключительно gcc-шный, или в MSVC он тоже есть ?

mes, если не такой typedef, а какая-либо другая конструкция может дать compile-time ошибку при совпадении констант ?


Сейчас делаю совершенно дурацким способом - перед компиляцией сам парсю свой исохдник и проверяю константы на уникальность, но IMHO это не выход...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 2.5.2011, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(borisbn @  2.5.2011,  15:57 Найти цитируемый пост)
И ещё вопрос, __COUNTER__ исключительно gcc-шный, или в MSVC он тоже есть ?

в MSVC тоже.

Цитата(borisbn @  2.5.2011,  15:57 Найти цитируемый пост)
Можешь показать пример ?

чичас smile

PM WWW   Вверх
mes
Дата 2.5.2011, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  2.5.2011,  14:57 Найти цитируемый пост)
если не такой typedef, а какая-либо другая конструкция может дать compile-time ошибку при совпадении констант ?

в любом случае нужен список.. получить его можно 
либо при определении нового типа _наследоваться_ от предыдущего и сохранять полученный список типов внутри определяемого типа,  
либо отдельно от определений составить список всех нужных типов..
Ну а имея список типов легко проверить на уникальность,  вхождение в нужный диапазон и многое другое..


Это сообщение отредактировал(а) mes - 2.5.2011, 16:20


--------------------
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0672 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.