Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Параметризация шаблона полем структуры


Автор: borisbn 24.3.2011, 19:44
Добрый день.
Есть такой код на MSVC 2008

Код

template< class T, class FieldType, FieldType T::*FieldPtr >
struct EqualBy {
    EqualBy( const FieldType & value ) : m_filedValue( value ) {}
    bool operator()( const T & r ) const {
        return m_filedValue == r.*FieldPtr;
    }
private:
    const FieldType m_filedValue;
};

...

struct S {
    int field1;
    ...
};
typedef EqualBy< S, int, &S::field1 > EqualByField1;

...
typedef std::vector< S > SVect;
SVect v;
SVect::const_iterator found = std::find_if( v.begin(), v.end(), EqualByField1( 42 ) );

всё работает.
Теперь я хочу внести EqualByField1 внутрь S
Код

struct S {
    int field1;
    ...

    typedef EqualBy< S, int, &S::field1 > EqualByField1;
};

чтобы сократить область видимости этого typedef'а, и чтобы вызывающий код выглядел бы так
Код

SVect::const_iterator found = std::find_if( v.begin(), v.end(), S::EqualByField1( 42 ) );

получаю ошибки
Цитата

error C2327: 'S::field1' : is not a type name, static, or enumerator
error C2065: 'field1' : undeclared identifier

Есть ли какое-то решение этой проблемки, кроме наследования от S ?
Код

struct SS : public S {
    typedef EqualBy< S, int, &S::field1 > EqualByField1; // так-то работает, но я так не хочу :)
};


Спасибо.

Автор: mes 24.3.2011, 20:12
Цитата(borisbn @  24.3.2011,  18:44 Найти цитируемый пост)
получаю ошибки

у гцц  вроде без проблем  :
http://liveworkspace.org/code/fcd7260c4081e05a051e8f0cc9d9946e

Добавлено через 59 секунд
Цитата(borisbn @  24.3.2011,  18:44 Найти цитируемый пост)
Есть ли какое-то решение этой проблемки, кроме наследования от S ?

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

Автор: borisbn 24.3.2011, 21:28
Цитата(mes @  24.3.2011,  20:12 Найти цитируемый пост)
у гцц  вроде без проблем  :

блин, когда же слово "стандарт" будет соответствовать своему назначению ?

Цитата(mes @  24.3.2011,  20:12 Найти цитируемый пост)
использовать namespace.. 

неа. хочу именно внутри этой структуры (модераторы, где иконка плачащий_ребёнок_валяющийся_на_полу_и_бьющий_по_полу_ногами_и_руками.gif ? ) smile

честно говоря, что namespace, что какая-то структура (наследованная или нет от основной) - не важно.

Автор: mes 24.3.2011, 21:49
Цитата(borisbn @  24.3.2011,  20:28 Найти цитируемый пост)
плачащий_ребёнок_валяющийся_на_полу_и_бьющий_по_полу_ногами_и_руками

может Вам в таком направлении пойти ? :
http://liveworkspace.org/code/7c1443260c80e1d00dff3b3096d4c3ad

Автор: borisbn 24.3.2011, 23:41
ну.... IMHO даже хуже, чем с наследованием (чисто эстетически)
что так
Код

 SVect::const_iterator found = std::find_if( v.begin(), v.end(), EqualBy<S,int> (&S::field1, 42 ) );

что так
Код

 SVect::const_iterator found = std::find_if( v.begin(), v.end(), EqualBy<S,int, &S::field1> ( 42 ) );

...
хочется, чтобы именно так
Код

 SVect::const_iterator found = std::find_if( v.begin(), v.end(), S::EqualByField1( 42 ) );

и чтобы EqualByField1 был внутри S. typedef'ом или ещё как-то - всё равно.
Я так понимаю, что стандартом это не запрещено, т.к. гцц это компилирует. Получается, что в студии, как водится, сделали свой "M$ Way"

жалко. а оч. хотелось всё-таки засунуть это внутрь структуры...

Автор: mes 25.3.2011, 00:08
Цитата(borisbn @  24.3.2011,  22:41 Найти цитируемый пост)
чисто эстетически

тогда смотрите (boost::/std:: ) bind

Цитата(borisbn @  24.3.2011,  22:41 Найти цитируемый пост)
хочется, чтобы именно так..
и чтобы EqualByField1 был внутри S. typedef'ом или ещё как-то - всё равно.

ну раз сильно хочется, ловите :
http://liveworkspace.org/code/7fb2f6365a7b3a631bb608bf4a5392ab
или опять не то ?

Добавлено @ 00:09
Цитата(borisbn @  24.3.2011,  22:41 Найти цитируемый пост)
а оч. хотелось всё-таки засунуть это внутрь структуры... 

все туда все равно не запихнете.. 
а запихивать внутрь структуры то, что не относится к ее реализации, очень плохой тон.. 

Автор: borisbn 25.3.2011, 00:34
Цитата(mes @  25.3.2011,  00:08 Найти цитируемый пост)
или опять не то ?

 smile ммммда. отрицать всегда легче, чем что-то предлагать.

Но, всё-таки, да. Не нравится. Меня с пелёнок (модераторы, где смайлик it's_just_a_joke.gif ?) учили, что описательную часть нужно располагать в h-нике, а реализацию - в cpp-шнике. В данном случае получается, что
Код
struct S {
    int field1;   
    
    static EqualBy<S,int> EqualByField1;
};

должен быть в h-нике, а
Код
EqualBy<S,int> S::EqualByField1(&S::field1);

в cpp-шнике.

mes, ладно, раз уж Вы не сказали сразу: "аааа, так нужно просто сделать что-то типа"
Код
using S::field1;

или 
Код
typedef EqualBy< S, int, typename &S::field1 > EqualByField1;

или ещё что-то в этом роде, то, скорее всего, это невозможно.  Во всяком случае на студии 2008. Завтра (ой... уже сегодня) попробую на 2010-й. Не получится - и  smile  с ним.

пока не закрываю...

Автор: mes 25.3.2011, 00:53
Цитата(borisbn @  24.3.2011,  23:34 Найти цитируемый пост)
раз уж Вы не сказали сразу: "аааа, так нужно просто сделать что-то типа"

исправляюсь : ааа, так тут же можно просто :
http://liveworkspace.org/code/9d7d6661d0ed36169eab1f58e62a6322
 smile 

Автор: mes 25.3.2011, 01:08
Цитата(borisbn @  24.3.2011,  23:34 Найти цитируемый пост)
попробую на 2010-й

там еще вот так должно быть можно :
http://liveworkspace.org/code/820a2aa615b7eebf2b131fde112ca62a

Автор: borisbn 27.3.2011, 10:26
хмммм, даже на билдере 5 (98-го года!!!) работает.
Похоже, что это глюк именно студии. (в 2010 тож не работает)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)