gccでのtemplateとfriend

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
kazuoni

gccでのtemplateとfriend

#1

投稿記事 by kazuoni » 15年前

お邪魔します。

自分は常に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

#2

投稿記事 by たかぎ » 15年前

super_typeはprivateなので、VC++でもコンパイルできないはずです。
正確なソースを貼ってください。

kazuoni

Re:gccでのtemplateとfriend

#3

投稿記事 by kazuoni » 15年前

とても大切な事を記述していませんでした。
super_typeはprotectedです。

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

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

YuO

Re:gccでのtemplateとfriend

#4

投稿記事 by YuO » 15年前

規格の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を使わなくて済むようにするとか……。

kazuoni

Re:gccでのtemplateとfriend

#5

投稿記事 by kazuoni » 15年前

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

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

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

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

たかぎ

Re:gccでのtemplateとfriend

#6

投稿記事 by たかぎ » 15年前

外回りしている間に解決したようですが...

いっそのこと、

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

class A
{
...
};

typedef TemplateForSingleton<A> SingletonA;

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

閉鎖

“C言語何でも質問掲示板” へ戻る