Саттер, 8 задача книги "Новые сложные задачи на C++"
От: Alexey F  
Дата: 02.01.09 23:02
Оценка: 12 (1)
Здравствуйте!

В книге Герба Саттера "Новые сложные задачи на C++" (2005 год издания) в восьмой задаче ("Дружественные шаблоны") вычитал, что в g++ проблематично объявить шаблонную функцию (располагающуюся внутри чужого пространства имён) другом класса (по крайней мере, в версии 3.4; в процессе проверки выяснилось, что и используемый мной Mingw 3.4.5 страдает аналогичной проблемой, а вот Mingw 4.3.0 уже воспринимает второй предложенный Саттером вариант решения проблемы "на ура").
Суть задачи заключалась в том, что немногие компиляторы способны правильно (следуя букве стандарта) прочитать объявление другом класса шаблонной функции внутри чужого пространства имён (далее пример):

namespace Some {
    template<class T>
    void func ( T* ptr ) {
        // ...
        delete ptr;
    }
}

class Test {
    ~Test (); // Естественно, private

    // Ошибка компиляции будет здесь у множества компиляторов:
    friend void Some::func ( Test* ); 

    // Эти строки понимают уже многие (но увы, не g++ 3.4.*):
    friend void Some::func<Test> ( Test* );
    // или:
    friend void Some::func<> ( Test* );
};


Как я понял из текста этой главы (задачи), Саттер не предложил способа решения этой проблемы для g++ (кроме как избавиться от обрамляющего функцию пространства имён или создать внутри пространства имён дополнительные классы (если я не прав, прошу поправить)). Немного помучавшись, нашёл вариант кода, устраивающий как (Mingw) g++ 3.4.*/g++ 4.3.0, так и, как впоследствии выяснилось, MS VC++ 2005 Express Edition:

namespace Some {
    template<class T>
    void func ( T* ptr ) {
        // ...
        delete ptr;
    }
}

class Test {
    ~Test () {}

    template<class T>
    friend void Some::func ( T* );
};


Однако, некоторые из протестированных мной компиляторов (Borland’вский и MS VC++ 6.0) отказались принимать такой код.

Теперь, собственно, вопрос:
"изобретённый" мной способ не противоречит стандарту? Может, эта проблема уже давно решена более красивым способом, не вызывающим нареканий вообще ни у одного компилятора? Если да, можно на него (на способ ) взглянуть?

P.S. Мои извинения, если я буду отвечать очень долго.
P.P.S. Вопрос задан из чистого любопытства и тяги к знаниям, ни в одном проекте конструкцию пока не применял
P.P.P.S. Не смог воспользоваться поиском: :

Поисковая система занята или временно недоступна.
DBG> errCode: 103

саттер новые сложные задачи на c++ восьмая задача g++ 3.4 friend template
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.