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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 25.05.2012, 22:13   #1
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию компиляторы, которые дружат по разному

Одному так подавай, другому - так подавай. А как же стандарт?
Неужели нет единого регламентированного синтаксиса объявления класса-френда, который одинаково понимают все компиляторы с++?

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

Код:
#include <iostream>

using namespace std;

template<class T>
class Prow
{
public:
    typedef T Result;
};


template<class T>
class PProw
{
public:
    typedef Prow<T> Result;
};

template<class T>
class CCrol
{
    typedef typename PProw<T>::Result Result;

    //гцц/мингв шуршит, студия ругается:
    //main.cpp:36: ошибка: C2242: имя typedef не может следовать за классом, структурой или объединением
    friend class PProw<T>::Result;

    //студийный шуршит, гцц/мингв ругается:
    //main.cpp:38: ошибка: a class-key must be used when declaring a friend
    //main.cpp:38: ошибка: friend declaration does not name a class or function
    friend Result;
};

int main()
{
    cout << "Hello World!" << endl;
    return 0;
}
Есть ли способ сделать единую синтаксическую запись: объявить френда, который является typedef в инстансе шаблонного класса. Да так, что бы её без изменений скушали и гцц/мингв, и студия?

Уж очень мне не хочется уродовать код препроцессором.
_Bers вне форума Ответить с цитированием
Старый 25.05.2012, 23:19   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

Код:
template<class T>
class CCrol
{
	friend class Prow<T>;
};
Цитата:
Уж очень мне не хочется уродовать код препроцессором.
правильно, нужно уродовать шаблонами)
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 вне форума Ответить с цитированием
Старый 25.05.2012, 23:34   #3
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
Код:
template<class T>
class CCrol
{
	friend class Prow<T>;
};

правильно, нужно уродовать шаблонами)
Другом является не инстанс Prow<T>
А тот тип, который будет забит в тайпдефе PProw<T>::Result
_Bers вне форума Ответить с цитированием
Старый 26.05.2012, 00:08   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2_Bers
Цитата:
//main.cpp:36: ошибка: C2242: имя typedef не может следовать за классом, структурой или объединением
friend class PProw<T>::Result;
судя стандарту, msvc тут не прав

можно сделать как то так
Код:
#include <iostream>

using namespace std;

template<class T>
class Prow {
public:
    typedef T Result;
};

template<
	typename T,
	template <typename> class P
>
class PProw {
public:
	typedef typename P<T>::Result Result;
};

template<
	typename T,
	template <typename> class P = Prow,
	template <typename, template <typename> class> class PP = PProw
>
class CCrol {
public:
	friend class P;
};

int main()
{
    CCrol<int> c;
    cout << "Hello World!" << endl;
    return 0;
}
тогда проблем не будет, но придется дополнительно передавать в CCrol необходимые шаблонные параметры
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; 26.05.2012 в 00:17.
pproger вне форума Ответить с цитированием
Старый 26.05.2012, 11:12   #5
_Bers
Старожил
 
Регистрация: 16.12.2011
Сообщений: 2,329
По умолчанию

Нет. Это не вариант. Зачем тащить толпу параметров и иметь долгоиграющие последствия, когда можно все эти параметры вывести из минимально возможного и фиксированного количества?

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

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

Код:
template<class T1, class T2=SEmpty>
class TLauncher: public ILauncher_t
{
public:
    typedef typename TMetaProgramm<T1,T2>::Strategy_t Executer_t;
    typedef typename TMetaProgramm<T1,T2>::Function_t Function_t;
    typedef typename TMetaProgramm<T1,T2>::Client_t Client_t;
    typedef typename TMetaProgramm<T1,T2>::Arg_t Arg_t;


    #ifdef __GNUC__
        #pragma message("System: gcc/mingw compiler option")
        friend class TMetaProgramm<T1,T2>::Strategy_t;
    #elif defined(_MSC_VER)
        #pragma message("System: MSC compiler option")
        friend Executer_t;
    #else
        #pragma message("System: WARNING! Unkown compiler option")
        friend class TMetaProgramm<T1,T2>::Strategy_t;
    #endif

    ...
Так то, вообще код был написан в студии, и он работает. Все что нужно - это подружить его с мингв/гцц
_Bers вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
на VISTA/7 и на XP отображается по разному( C4eLoveK Общие вопросы Delphi 0 12.04.2012 21:02
Почему не дружат динамич.массивы и switch FelixXXI Общие вопросы C/C++ 2 22.10.2011 18:38
Оформить ссылки по-разному Krasi HTML и CSS 1 12.07.2010 14:51
Ассемблер и Паскаль не дружат... Monte-Kristo Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 7 16.06.2009 13:03