Re[2]: доступ к полям с помощью шаблона
От: Evgeny.Panasyuk Россия  
Дата: 07.02.13 09:23
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>1. Почему при автоматической генерации функций get из шаблонов разного типа инстанцирования между ними конфликт, а если те же самые функции get написать руками, то конфликта нет?


добавь в класс a:
using b<char>::get;
using b<int>::get;
using b<float>::get;
Re[6]: доступ к полям с помощью шаблона
От: pepsicoca  
Дата: 07.02.13 10:36
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, pepsicoca, Вы писали:


P>>А раньше он не так говорил.


EP>Пруф?


Да пожалуйста, у нас это как отче наш:


http://lib.ru/CPPHB/cpptut.txt

— Определяйте интерфейс так, чтобы открывать минимальное количество
требуемой информации:
- Используйте, всюду где это можно, частные данные и функции-члены.
— Используйте описания public или protected, чтобы отличить
запросы разработчика производных классов от запросов обычных
пользователей.


И еще в других разных местах, например:


http://lib.web-malina.com/getbook.php?bid=4536&amp;page=5

Правила Правой Руки (*)

Здесь приводится набор правил, которых вам хорошо бы
придерживаться изучая C++. Когда вы станете более опытны, вы можете
превратить их в то, что будет подходить для вашего рода
деятельности и вашего стиля программирования. Они умышленно сделаны
очень простыми, поэтому подробности в них опущены. Не воспринимайте
их чересчур буквально. Написание хороших программ требует ума,
вкуса и терпения. Вы не собираетесь как следует понять это с самого
начала; поэкспериментируйте!
[1] Когда вы программируете, вы создаете конкретное
представление идей вашего решения некоторой задачи. Пусть
структура отражает эти идеи настолько явно, насколько это
возможно:
[1] Если вы считате "это" отдельным понятием, сделайте его
классом.

____________________
(*) Некоторые легко запоминаемые эмпирические правила, "Правила-
помошники." (прим. перев.)

— стр 18 —

[2] Если вы считате "это" отдельным объектом, сделайте его
объектом некоторого класса.
[3] Если два класса имеют общим нечто существенное, сделайте
его базовым классом. Почти все классы в вашей программе
будут иметь нечто общее; заведите (почти) универсальный
базовый класс, и разработайте его наиболее тщательно.
[2] Когда вы определяете класс, который не реализует
некоторый математический объект, вроде матрицы или
комплексного числа, или тип низкого уровня, вроде связанного
списка, то:
[1] Не используйте глобальные данные.
[2] Не используйте глобальные функции (не члены).
[3] Не используйте открытые данные-члены.
[4] Не используйте друзей, кроме как чтобы избежать [a], [b]
или [c].
[5] Не обращайтесь к данным-членам или другим объектам
непосредственно.
[6] Не помещайте в класс "поле типа"; используйте виртуальные
функции.
[7] Не используйте inline-функции, кроме как средство
существенной оптимизации.

Re[3]: доступ к полям с помощью шаблона
От: pepsicoca  
Дата: 07.02.13 14:09
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Здравствуйте, pepsicoca, Вы писали:


P>>1. Почему при автоматической генерации функций get из шаблонов разного типа инстанцирования между ними конфликт, а если те же самые функции get написать руками, то конфликта нет?


EP>добавь в класс a:

EP>
EP>using b<char>::get;
EP>using b<int>::get;
EP>using b<float>::get;
EP>


Прикольно.

На Borland C++ Builder транслируется, но не работает (достает ерунду вместо значений 1,2,3).
На MSVC 2010 транслируется и работает.
Вариант без шаблона транслируется и работает и там и там.
Re: доступ к полям с помощью шаблона
От: akochnev Россия  
Дата: 08.02.13 07:32
Оценка:
Здравствуйте, pepsicoca, Вы писали:
P>1. Как быть и что делать? Неужели нужно писать вручную все функции доступа к полям?

class Foo
{
public:
    char  field1;
    int   field2;
    float field3;
public:
    template<typename T, typename F>
    T get(T F::*field) const
    {
        return this->*field;
    }
};

std::cout << foo.get(&Foo::field1) << std::endl;

Не нравиться тут упоминание имени класса.
Можно объявить глобальную переменную
const char Foo::*field1 = &Foo::field1;

и использовать

std::cout << foo.get(field1) << std::endl;
Re[2]: доступ к полям с помощью шаблона
От: pepsicoca  
Дата: 08.02.13 09:52
Оценка:
Здравствуйте, akochnev, Вы писали:

Идея кудрявая, но:

1. Смущают открытые поля field.
2. Смущает передача параметра в функцию по значению. Это уменьшает производительность, особенно если поле большое.
3. Смущает возврат параметра из функции по значению. Это уменьшает производительность, особенно если поле большое.
4. Хотелось бы получать из функции указатель на поле и передавать в нее хотя бы указатель на поле. Но пока максимум того, что у меня получилось это передать значение и получить указатель:


    template<typename T, typename F>
    T* get1(T F::*field) 
    {
        return &(this->*field);
    }


В идеале надо бы ничего не передавать вообще.
Re[3]: доступ к полям с помощью шаблона
От: akochnev Россия  
Дата: 08.02.13 12:08
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>Идея кудрявая, но:


P>1. Смущают открытые поля field.

меня тоже

P>2. Смущает передача параметра в функцию по значению. Это уменьшает производительность, особенно если поле большое.

В геттер передается только указатель на член класса.

P>3. Смущает возврат параметра из функции по значению. Это уменьшает производительность, особенно если поле большое.

Можно возвращать ссылку, проблем не вижу
template<typename T, typename F>
const T& get(T F::*field) const
{
    return this->*field;
}


P>4. Хотелось бы получать из функции указатель на поле и передавать в нее хотя бы указатель на поле. Но пока максимум того, что у меня получилось это передать значение и получить указатель:

template<typename T, typename F>
void get(F field, T& result) const
{
    result = this->*field;
}


P>В идеале надо бы ничего не передавать вообще.

Так не получится сделать, потому что это подразумевает у класса функции, которые отличаются только типом возвращаемого значения

Я бы посоветовал вообще избегать делать что-то подобное в коде, то есть очевидную задачу решать не очевидным путем.
Тем более что большинство IDE умеют автоматически генерить геттеры и сеттеры.
Re[4]: доступ к полям с помощью шаблона
От: pepsicoca  
Дата: 08.02.13 12:12
Оценка:
P>>2. Смущает передача параметра в функцию по значению. Это уменьшает производительность, особенно если поле большое.
A>В геттер передается только указатель на член класса.

В геттер передается объект типа T. То есть либо char, либо int, либо float (в примере).
Если тип T не такой маленький, а побольше, то...
Re[3]: доступ к полям с помощью шаблона
От: Erop Россия  
Дата: 08.02.13 13:22
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>В идеале надо бы ничего не передавать вообще.


А как ты хотел бы задавать гуттеры?..
Но номеру поля, по элементу перечисления, как-то ещё?..

Собственно всё упирается в два аспекта.
1) Как задавать геттеры
2) Как представлять список полей, к которым нужны геттеры?

Один путь -- заводим специальные шаблоны типов, заворачивающих поля. Ну, то есть, есть такой шаблон вроде
template<typename T>class CFieldWithGetter {
public:
    CFieldWithGetter();
//    CFieldWithGetter( const CFieldWithGetter& other ) : body( other.body ) {}
    template<typename T1>
    CFieldWithGetter( const T1& a1 ) : body( a1 ) {}
    template<typename T1, typename T2>
    CFieldWithGetter( const T1& a1, const T2& a2 ) : body( a1, a2 ) {}
    //  и т. д.

    void swap( T& other ) { std::swap( body, other ); }
    void swap( CFieldWithGetter& other ) { std::swap( body, other.body ); }

    // В принципе вместо этого можено сеттер написать
    void opearator = ( const T& other ) { body = other; }
    void opearator = ( const CFieldWithGetter& other ) { body = other.body; }

    //  Внимание!!! Всё ради этого!!!
    const T& Get() const { return body; }
private:
    T body;
};
ну и фигачишь свою структурку в виде:
struct MyData {
    CFieldWithGetter<int> field_1;
    CFieldWithGetter<char> field_1;
    CFieldWithGetter<std::string> field_1;
};
или гуглишь что-то вроде "свойства для C++", можно прямо на КЫВТе

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

В общем напиши кусок клиентского кода, как бы ты хотел, чт бы всё было, когда всё будет.
И можно будет что-то предложить
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: доступ к полям с помощью шаблона
От: serjjj Россия  
Дата: 10.02.13 21:44
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>Публичные поля это ересь, так учит нас Страуструп.


Если говорить о классах, то все верно. Но что бы структура стала классом не достаточно просто подписать слово "class" вначале. Необходимо выполнить некоторые условия. Так если есть много полей и нет особой логики работы с ними, то это скорее всего структура. Лучше сделать "структуру с конструктором", и не париться такими искусственно созданными проблемами.
Re[3]: доступ к полям с помощью шаблона
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 11.02.13 10:24
Оценка:
Здравствуйте, Kernan, Вы писали:

A>>это называется std::tuple, или boost::fusion, в зависимости от того что вы с этими полями собираетесь делать.

K>А это назвается из пушки по воробьям .
Минусующие, вы хотя бы примерчик с fusion написали перед тем, как минус ставить. Тупл не интересует.
Sic luceat lux!
Re[7]: доступ к полям с помощью шаблона
От: Evgeny.Panasyuk Россия  
Дата: 11.02.13 18:01
Оценка:
Здравствуйте, pepsicoca, Вы писали:

P>>>А раньше он не так говорил.

EP>>Пруф?
P>Да пожалуйста, у нас это как отче наш:
P>

P>http://lib.ru/CPPHB/cpptut.txt


"Второе дополненное издание" As C++ evolved, a second edition was published in July <b>1991</b>


P>И еще в других разных местах, например:

P>

P>http://lib.web-malina.com/getbook.php?bid=4536&amp;page=5


А это вообще походу первое The first edition of The C++ Programming Language was published in <b>1985</b>


P>

P> Правила Правой Руки (*)
P> Здесь приводится набор правил, которых вам хорошо бы
P>придерживаться изучая C++. Когда вы станете более опытны, вы можете
P>превратить их в то, что будет подходить для вашего рода
P>деятельности и вашего стиля программирования. Они умышленно сделаны
P>очень простыми, поэтому подробности в них опущены. Не воспринимайте
P>их чересчур буквально. Написание хороших программ требует ума,
P>вкуса и терпения. Вы не собираетесь как следует понять это с самого
P>начала; поэкспериментируйте!

P> [2] Когда вы определяете класс, который не реализует
P> некоторый математический объект, вроде матрицы или
P> комплексного числа, или тип низкого уровня, вроде связанного
P> списка, то:
P> [3] Не используйте открытые данные-члены.


Ключевое слово — класс. Если все поля объекта, может прочитать/изменить кто-угодно, напрямую или через getters&setters то это структура, а не класс, так тут нет никаких инвариантов (а если есть — то значит любой может mess with it).

The C++ Programming Language Third Edition:

10.2.8 Structures and Classes [class.struct]
...
Which style you use depends on circumstances and taste. I usually prefer to use struct for classes
that have all data public
. I think of such classes as ‘‘not quite proper types, just data structures.’’

,

10.5 Advice [class.advice]
Use public data (structs) only when it really is just data and no invariant is meaningful for the
data members
; §10.2.8.

Re: доступ к полям с помощью шаблона
От: Vamp Россия  
Дата: 11.02.13 18:40
Оценка:
P>Нужен доступ к полям класса.
P>Каждый раз писать новую функцию getX не хочется.
Сделать поля public.
Да здравствует мыло душистое и веревка пушистая.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.