ページ 11

gccでのtemplateとfriend

Posted: 2010年3月24日(水) 11:17
by kazuoni
お邪魔します。

自分は常にVC 9.0でコンパイルしていて、以下のクラスはコンパイルできていました。
template< typename T >
class Template{
typedef Template<T> super_type;
...
};

class A : public Template<A>{
friend super_type;
...
};
しかし、gccでは以下のエラーではじかれます。

1>error: a class-key must be used when declaring a friend
1>error: friend declaration does not name a class or function
...

いろいろなサイトを見た結果、次のような解決策がありました。が、すべてダメでした。

1. friend class super_type;
結果 1>error: using typedef-name 'Template<A>::super_type' after 'class'

2. friend class Template<A>::super_type;
結果 1>error: using typedef-name 'Template<A>::super_type' after 'class'

gccのバージョンは3.4.4、4.3.0どちらもダメでした。

解決するにはどうしたらよいでしょうか?
よろしくお願いします。

Re:gccでのtemplateとfriend

Posted: 2010年3月24日(水) 11:46
by たかぎ
super_typeはprivateなので、VC++でもコンパイルできないはずです。
正確なソースを貼ってください。

Re:gccでのtemplateとfriend

Posted: 2010年3月24日(水) 12:01
by kazuoni
とても大切な事を記述していませんでした。
super_typeはprotectedです。

一応、ソースをあげておきます。

#追記
あげたコードはtypenameとか使ってますが、
あがいた結果ですので気にしないでください^^; 画像

Re:gccでのtemplateとfriend

Posted: 2010年3月24日(水) 15:21
by YuO
規格の11.4 Friendsに,
> An elaborated-type-specifier shall be used in a friend declaration for a class
とあります。ちなみに,elaborated-type-specifierは以下のようになります。
elaborated-type-specifier:
class-key '::'(opt) nested-name-specifieropt identifier
class-key '::'(opt) nested-name-specifier(opt) template(opt) template-id
'enum' '::'(opt) nested-name-specifier(opt) identifier
typename '::'(opt) nested-name-specifier identifier
typename '::'(opt) nested-name-specifier template(opt) template-id
# 非装飾の文字は原文斜体,''で括られた文字は原文では非装飾,(opt)は原文ではoptが下付き。

さらに,7.1.5.3 Elaborated type specifiersには
> If the identifier resolves to a typedef name or a template type-parameter, the elaborated-type-specifier is ill-formed.
とあり,friendにはtypedef名は使えないことになります。

このため,typedef名はあきらめ,Template<A>をfriendにした方がよいでしょう。
# というか,色々面倒なのでfriendを使わなくて済むようにするとか……。

Re:gccでのtemplateとfriend

Posted: 2010年3月24日(水) 17:38
by kazuoni
ご指摘いただいたように、typedefを用いなければ、うまくいきました。
新しいものばかり使っているので、この辺りは全く分かりませんでした。
規格は読まないといけませんね。。(英語嫌いの自分には敷居はかなり高いですが・・・)

> #というか,色々面倒なのでfriendを使わなくて済むようにするとか……。
正直、テンプレートを使わなくて済むようにするのが最善なのかもしれません。。

自分の問題は解決したので、これで解決とさせていただきます。
ご回答していただきありがとうございました。

次回もよろしくお願いします。 画像

Re:gccでのtemplateとfriend

Posted: 2010年3月24日(水) 22:35
by たかぎ
外回りしている間に解決したようですが...

いっそのこと、

template <class T>
class TemplateForSingleton : public T
{
...
};

class A
{
...
};

typedef TemplateForSingleton<A> SingletonA;

のようにすると、うまくいく場合があります。