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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> требуются ваши телепатические способности %), ну не знаю как еще в пяти словах назвать 
V
    Опции темы
boostcoder
Дата 29.5.2012, 20:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



все те же "бараны"..сериализация...

код:
Код

#include <iostream>
#include <sstream>

namespace yas {

template<typename T, typename U>
T cast_to(U u) {
   return static_cast<T>(u);
}

template<typename T, typename U>
T& cast_from(U& u) {
   return *reinterpret_cast<T*>(&u);
}

struct oarchive {
   template<typename T>
   oarchive& operator& (const T&) {
      return *this;
   }
};

struct iarchive {
   template<typename T>
   iarchive& operator& (T&) {
      return *this;
   }
};

} // namespace yas

template<typename OA, typename IA>
bool enum_test() {
   enum enum1 { _1_1, _1_2, _1_3, _1_4 };
   enum class enum2: char { _2_1, _2_2, _2_3, _2_4 };

   OA oa;
   oa
   & yas::cast_to<int>(_1_2)
   & yas::cast_to<int>(_1_4)
   & yas::cast_to<int>(enum2::_2_1)
   & yas::cast_to<int>(enum2::_2_3);
   
   enum1 e11, e12;
   enum2 e21, e22;
   
   IA ia;
   ia
   & yas::cast_from<int>(e11)
   & yas::cast_from<int>(e12)
   & yas::cast_from<int>(e21)
   & yas::cast_from<int>(e22);
   
   return true;
}

int main() {
   enum_test<yas::oarchive, yas::iarchive>();
   std::cout << "ping" << std::endl;
}

http://liveworkspace.org/code/1c4390aba0b4...dbcbb1379eeefe6
компилится и работает.

но точно такой же код, в составе проекта выдает такие ошибки:
Цитата

main.cpp: In function 'bool enum_test() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]':
main.cpp:1901:2:   instantiated from 'bool tests() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]'
main.cpp:1956:60:   instantiated from here
main.cpp:154:2: error: no matching function for call to 'enum_cast_to(enum_test() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]::enum1)'
main.cpp:154:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:41:3: note: template<class T, class U> T yas::enum_cast_to(U)
main.cpp:154:2: error: no matching function for call to 'enum_cast_to(enum_test() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]::enum1)'
main.cpp:154:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:41:3: note: template<class T, class U> T yas::enum_cast_to(U)
main.cpp:159:2: error: no matching function for call to 'enum_cast_from(enum_test() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]::enum1&)'
main.cpp:159:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:46:4: note: template<class T, class U> T& yas::enum_cast_from(U&)
main.cpp:159:2: error: no matching function for call to 'enum_cast_from(enum_test() [with OA = yas::binary_mem_oarchive, IA = yas::binary_mem_iarchive]::enum1&)'
main.cpp:159:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:46:4: note: template<class T, class U> T& yas::enum_cast_from(U&)
main.cpp: In function 'bool enum_test() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]':
main.cpp:1901:2:   instantiated from 'bool tests() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]'
main.cpp:1957:56:   instantiated from here
main.cpp:154:2: error: no matching function for call to 'enum_cast_to(enum_test() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]::enum1)'
main.cpp:154:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:41:3: note: template<class T, class U> T yas::enum_cast_to(U)
main.cpp:154:2: error: no matching function for call to 'enum_cast_to(enum_test() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]::enum1)'
main.cpp:154:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:41:3: note: template<class T, class U> T yas::enum_cast_to(U)
main.cpp:159:2: error: no matching function for call to 'enum_cast_from(enum_test() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]::enum1&)'
main.cpp:159:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:46:4: note: template<class T, class U> T& yas::enum_cast_from(U&)
main.cpp:159:2: error: no matching function for call to 'enum_cast_from(enum_test() [with OA = yas::text_mem_oarchive, IA = yas::text_mem_iarchive]::enum1&)'
main.cpp:159:2: note: candidate is:
../../include/yas/tools/enum_cast.hpp:46:4: note: template<class T, class U> T& yas::enum_cast_from(U&)


содержимое файла enum_cast.hpp:
Код

#ifndef _yas__enum_cast_hpp__included_
#define _yas__enum_cast_hpp__included_

namespace yas {

/***************************************************************************/

template<typename T, typename U>
T enum_cast_to(U u) {
    return static_cast<T>(u);
}

template<typename T, typename U>
T& enum_cast_from(U& u) {
    return *reinterpret_cast<T*>(&u);
}

/***************************************************************************/

} // namespace yas

#endif // _yas__enum_cast_hpp__included_



подскажите, чего оно от меня кочет? битый час выносит мне моцг smile 

спасибо.

Добавлено @ 20:50
да, в проекте эти функции зовутся enum_cast_to и enum_cast_from
это в воспроизводящем примере я их укоротил.


Это сообщение отредактировал(а) boostcoder - 29.5.2012, 22:25
PM WWW   Вверх
hawk3500
Дата 29.5.2012, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Как я понимаю, ты пытаешься вызвать функцию, объявление которой компилятор нашел, а определение нет. Может, в определении у тебя имя функции с опечаткой?
--------------------
воин dzen'a
PM MAIL   Вверх
boostcoder
Дата 29.5.2012, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(hawk3500 @  29.5.2012,  22:05 Найти цитируемый пост)
объявление которой компилятор нашел, а определение нет.

это же шаблонные функции. у них декларация и реализация в одном "флаконе" smile

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


Бывалый
*


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

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



А можно увидеть как в проекте вы вызываете enum_cast_from ?

Добавлено через 3 минуты и 8 секунд
как она объявлется в том файле где используется?
--------------------
воин dzen'a
PM MAIL   Вверх
boostcoder
Дата 29.5.2012, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(hawk3500 @  29.5.2012,  22:46 Найти цитируемый пост)
как в проекте вы вызываете enum_cast_from ?

код в топике, полностью идентичен тому что в проекте за исключением того, что в проекте помимо функции enum_test<>() еще куча других функций для других тестов.

Добавлено через 1 минуту и 8 секунд
Цитата(hawk3500 @  29.5.2012,  22:46 Найти цитируемый пост)
как она объявлется в том файле где используется?

кто "она" ? функция enum_cast_from?
она в другом файле декларирована. текст того файла я так же привел в топике.

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


Бывалый
*


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

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



я про вызов спрашивал именно к тому , что указывается ли явно при вызове к примеру enum_cast_to спецмфмкация шаблона.

Добавлено через 1 минуту и 34 секунды
Извеняюсь....не увидел сразу что на enum_test() тоже "ругаются".....
--------------------
воин dzen'a
PM MAIL   Вверх
boostcoder
Дата 30.5.2012, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



более никто не жив?
PM WWW   Вверх
Static
Дата 30.5.2012, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Прошу прощения за возможную глупость - но
Я правильно понял, что объявление шаблонной функции и ее реализация (в проекте) находятся в разных файлах? Поддерживает ли Ваш компилятор такое? ЕМНИП, некоторые так не умели.
--------------------
Я не настолько безнадежен, как кажется...
PM MAIL   Вверх
boostcoder
Дата 30.5.2012, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(Static @  30.5.2012,  11:12 Найти цитируемый пост)
Я правильно понял, что объявление шаблонной функции и ее реализация (в проекте) находятся в разных файлах?

нет. все в одном хидере.

проблема, оказывается, была из-за того, что в С++03 нельзя использовать локальные типы в качестве параметра шаблона. а в реальном проекте используется именно С++03.

всем спасибо.

PM WWW   Вверх
volatile
Дата 31.5.2012, 01:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 37
Всего: 85



boostcoder, Это к первоначальному вопросу не отностися, но в коде есть грубая ошибка.

Цитата(boostcoder @  29.5.2012,  20:40 Найти цитируемый пост)
   enum class enum2: char { _2_1, _2_2, _2_3, _2_4 };

Цитата(boostcoder @  29.5.2012,  20:40 Найти цитируемый пост)
template<typename T, typename U>
T& cast_from(U& u) {
   return *reinterpret_cast<T*>(&u);
}

Цитата(boostcoder @  29.5.2012,  20:40 Найти цитируемый пост)
IA ia;
   ia
   & yas::cast_from<int>(e11)
   & yas::cast_from<int>(e12)
   & yas::cast_from<int>(e21)
   & yas::cast_from<int>(e22);
   


При чтении из ia, по адресу переменной енум, будет записан int.
Фактически запишется 4 байте (int) на место где находится один байт (enum2: char).
Код затирает соседние ячейки!

Цитата(boostcoder @  29.5.2012,  20:40 Найти цитируемый пост)
enum class enum2: char {
Этот код правда на С++03 вообще не скомпилится, поэтому можно сказать что реально ошибка будет только на 2011.

Цитата(boostcoder @  29.5.2012,  20:40 Найти цитируемый пост)
 enum enum1 { _1_1, _1_2, _1_3, _1_4 };
Этот код видимо из реального С++03 проекта, и если подходить строго, то и здесь не все чисто.
Стандарт С++03 не оговаривет что енум будет обязательно длиной int
Цитата(ISO/IEC 14882:2003)
7.2/5 The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration.  It is implementation-defined which integral type is used as the underlying type for an enumeration

Так что, записывать по адресу енума, инт - формально это и в С++03 грубая ошибка.
(хотя реально код в С++03, вероятно, будет работать)

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


pattern`щик
****


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

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



Цитата(volatile @  31.5.2012,  01:54 Найти цитируемый пост)
Фактически запишется 4 байте (int) на место где находится один байт (enum2: char).
Код затирает соседние ячейки!

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

enum enum_test_enum1 { _1_1, _1_2, _1_3, _1_4 };

#if defined(YAS_HAS_ENUM_CLASS)
enum class enum_test_enum2: char { _2_1, _2_2, _2_3, _2_4 };
#endif // defined(YAS_HAS_ENUM_CLASS)

template<typename OA, typename IA>
bool enum_test() {
    OA oa1;
    oa1 & yas::enum_cast_to<int>(_1_2)
         & yas::enum_cast_to<int>(_1_4);

    enum_test_enum1 e11, e12;
    IA ia1(oa1.get_intrusive_buffer());
    ia1 & yas::enum_cast_from<int>(e11)
         & yas::enum_cast_from<int>(e12);

    if ( e11 != _1_2 || e12 != _1_4 ) {
        std::cout << "ENUM deserialization error! [1]" << std::endl;
        return false;
    }

#if defined(YAS_HAS_ENUM_CLASS)

    OA oa2;
    oa2 & yas::enum_cast_to<unsigned char>(enum_test_enum2::_2_1)
         & yas::enum_cast_to<unsigned char>(enum_test_enum2::_2_3);

    enum_test_enum2 e21, e22;
    IA ia2(oa2.get_intrusive_buffer());
    ia2 & yas::enum_cast_from<unsigned char>(e21)
         & yas::enum_cast_from<unsigned char>(e22);

    if ( e21 != enum_test_enum2::_2_1 || e22 != enum_test_enum2::_2_3 ) {
        std::cout << "ENUM deserialization error! [2]" << std::endl;
        return false;
    }

#endif // defined(YAS_HAS_ENUM_CLASS)

    return true;
}

https://github.com/niXman/yas/blob/master/t...s/base/enum.hpp

Цитата(volatile @  31.5.2012,  01:54 Найти цитируемый пост)
С++03 не оговаривет что енум будет обязательно длиной int

этого я тоже не знал.
но так же, мне неизвестен компилятор где бы это было не так smile

спасибо.

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


Эксперт
****


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

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



Цитата(boostcoder @  31.5.2012,  09:50 Найти цитируемый пост)
но так же, мне неизвестен компилятор где бы это было не так

Дебилдер. Там по-умолчанию енумы 1 байт. Поэтому если мне требуется, чтобы енум гулял по сети, записывался в файл и т.п. (т.е. чтобы его размер был гарантированно 4 байта вне зависимости от настроек) то я добавляю в конец списка 0x7FFFFFFF
Код
enum Type {
    Type_one,
    Type_two,
    Type_three,
    Type_FORCE_INT = 0x7FFFFFFF
};


хотел подсказать, что за такую помощь неплохо было бы volatile поблагодарить плюсиком, но вижу, что опоздал)))

Это сообщение отредактировал(а) borisbn - 31.5.2012, 10:50


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


pattern`щик
****


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

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



жуть какая smile

Добавлено через 9 минут и 10 секунд
да, для YAS не заявлена поддержка билдера)
PM WWW   Вверх
volatile
Дата 31.5.2012, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 37
Всего: 85



вот здесь предлагается использовать спец. шаблон для обхода неопределенности с типом енума в с++03. (с первого взгляда, довольно юзабельно)...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0723 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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