Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 31.01.2012, 14:53   #1
impus
Новичок
Джуниор
 
Регистрация: 31.01.2012
Сообщений: 3
По умолчанию беда с typename

Добрый день. Смешной вопрос, но ответа не знаю... (
Задача: вынести из хэдера описание метода в файл inl.
Не могу заставить скомпилироваться конструкцию, которая опишет тело метода...

HEADER

template<class T, class G>
class Logic: public OtherClass
{
public:
typedef localname::intrusive_ptr<G> LPG;
typedef std::vector<LPG> GList;
...
CREF(GList) getG () const;
...
}

INLINE

template<class T, class G>
inline typename CREF(Logic<T, G>::GList) Logic<T,G>::getG() const

{
...
}

где
#define CREF(A) const A&

Так вот. Вся проблема в этом самом макросе. Не могу его приткнуть так, чтобы конструкция стала валидной. Есть ограничения: вводить новые типы нельзя. И без макроса работает... Но нужно именно с ним конструкцию построить

Спасибо
impus вне форума Ответить с цитированием
Старый 01.02.2012, 12:32   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2impus
1. выдавать из класса наружу члены-данные, а тем более контейнер - плохая идея. добавь в класс нужные тебе методы для работы с контейнером.
2.
Цитата:
Задача: вынести из хэдера описание метода в файл inl.
опять же, нельзя в с++ отделять шаблонное определение от реализации.
3.
Код:
#define CREF(A) const A&
в с++ такой бред не используют. используют следующий бред:
Код:
template <typename T>
class A {
public:
	typedef T &reference;
	typedef const T &const_reference;

	A(T t) : m_t(t)
	{}

	const_reference foo() const
	{
		cout << "called const ref foo" << endl;
		return m_t;
	}

	reference foo()
	{
		cout << "called non const ref foo" << endl;
		return m_t;
	}

private:
	T m_t;
};

template <typename T>
void foo1(A<T> &a)
{
	typename A<T>::reference ref = a.foo();
}

template <typename T>
void foo2(const A<T> &a)
{
	typename A<T>::const_reference ref = a.foo();
}

int main(int argc)
{
	A<int> a(10);

	foo1(a);
	foo2(a);

	return 0;
}
подробнее читай про traits (характеристики). читать можно в книге по шаблонам Вандервуда, либо у Александреску
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance

Последний раз редактировалось pproger; 01.02.2012 в 13:47.
pproger вне форума Ответить с цитированием
Старый 01.02.2012, 20:32   #3
impus
Новичок
Джуниор
 
Регистрация: 31.01.2012
Сообщений: 3
По умолчанию

Спасибо большое за развернутый ответ, но дело в том, что мне надо внести озвученные изменения в уже существующий код. Я не могу отказаться от макроса. Мне сказали вынести описания методов в отдельный файл, потому что код стал некомфортно читаем.
Определение от реализации отделять технически можно. Есть методы в этом классе, типа Logic<T, G>::GList
И они прекрасно компилируются.
Возможно сделать конструкцию валидной?
impus вне форума Ответить с цитированием
Старый 01.02.2012, 21:57   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2impus
Цитата:
Возможно сделать конструкцию валидной?
для этого нужно понимать, что ты делаешь. давай разберемся.
самый ближайший к валидному коду (но тем не менее, он нерабочий) это
Код:
template<class T, class G>
CREF(typename Logic<T, G>::GList) Logic<T,G>::getG() const
{
}
почему он не рабочий? препроцессор думает, что мы вызываем макрос CREF с двумя параметрами. первый параметр - все, что СЛЕВА от запятой (зеленое), второй - все, что справа (красное). у нас же макрос с 1 параметром --> ошибка. можно попробовать написать так
Код:
template<class T, class G>
CREF(typename (Logic<T, G>::GList)) Logic<T,G>::getG() const
{
}
с кол-вом параметров тут все нормально, но после работы препроцессора получим
Код:
template<class T, class G>
const typename (Logic<T, G>::GList)& Logic<T,G>::getG() const
{
}
что уже не пропустит синтаксический анализатор. как этого избежать, не меняя макроса я не знаю.

Проблема в том, что препроцессор разработан для использования в языке СИ, где таких проблем нет. в С++ препроцессор себя изжил.

если твой компилятор поддерживает следующую конструкцию, можешь попробовать написать так:
Код:

#define CREF(...) const __VA_ARGS__&

template<class T, class G>
CREF(typename Logic<T, G>::GList) Logic<T,G>::getG() const
{
}
и это уже соберется.

но опять же. НЕЛЬЗЯ, НЕЛЬЗЯ ТАК ПИСАТЬ В С++.


Как быть в данной ситуации? Заменить макрос на шаблон!
Код:
template <typename T>
struct CREF {
	typedef T const &type;
};

template<class T, class G>
class Logic {
public:
	typedef std::vector<T> GList;

	typename CREF<GList>::type getG () const;
};

template<class T, class G>
typename CREF<typename Logic<T, G>::GList>::type Logic<T,G>::getG() const
{
}
но мне больше нравятся характеристики
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 02.02.2012, 13:10   #5
impus
Новичок
Джуниор
 
Регистрация: 31.01.2012
Сообщений: 3
По умолчанию

спасибо большое :-)
impus вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Беда капец!!! VintProg Операционные системы общие вопросы 18 31.08.2011 16:25
Беда с windows.h nury Visual C++ 7 16.08.2011 10:15
беда Морячок Паскаль, Turbo Pascal, PascalABC.NET 3 05.06.2010 15:41