6

これは、コンパイル エラーの原因となっているクラス テンプレートのスニペットです。

/* Secondary index class */
template<class TKey, class TVal, class key_traits, class val_traits>
template<class TSecKey, class sktraits> 
class CBtreeDb<TKey, TVal, key_traits, val_traits>::CDbSecondaryIndex: protected CBtreeDb<TKey, TVal>, public IDeallocateKey
{
public:
 typedef TSecKey           skey_type;
 typedef typename sktraits                         skey_traits;
 typedef CNewDbt<TSecKey, sktraits>                CDbSKey;
 typedef typename iterator_t<TSecKey, skey_traits> iterator;
 typedef typename iter_lower_bound_t<skey_type>    iter_lower_bound;
 typedef typename iter_upper_bound_t<skey_type>    iter_upper_bound;

 CDbSecondaryIndex(CDbEnv* pEnv, u_int32_t flags, bool bAllowDuplicates=false):
  CBtreeDb(pEnv, flags, bAllowDuplicates)
 {

 }

    // Class implementation continues ...
};

表示されるコンパイラ エラー メッセージは次のとおりです。

expected nested-name-specifier before 'sktraits'.

実際には、このエラーは、typedefその後に続くすべての宣言で発生します。typename

XPでVS2005およびVS2008を使用して、過去にこのコードを正常にコンパイルしました。

現在、gcc 4.4.1 を使用して Ubuntu 9.10 でビルドしています。

Google でこのエラーを調べたtypenameところ、行 (エラーが発生した場所) には必要ないようです。これは、その位置の識別子が型であるという標準的な前提があるためです。typenameg++ は、宣言が修飾されていることを期待しているため (つまり、A::B)、不平を言っているようです。

これは問題の正しい診断ですか? もしそうなら、どうすれば を「完全に認定」できtypenameますか?

要するに、どうすればこの問題を解決できますか?

4

2 に答える 2

7

typename従属名が実際にタイプであることを指定するために必要です。あなたの名前は従属名ではないため、notypenameは必須または許可されません。

更新標準には、実際には次の構文定義があります。

typename-specifier :
    typename ネストされた名前指定子 識別子
    typename ネストされた名前指定子 template opt simple-template-id

typename キーワードを使用できる他の 2 つの場所は、テンプレート パラメーター リストとusing宣言です (後者の場合、ネストされた名前指定子が後に続く必要があります)。

于 2011-12-01T04:38:23.497 に答える
1

以下は許可されていません。

template<class A>
template<class B> class F { ... };

template<>クラス/関数定義の前に最大 1 つの仕様を持つことができます。

于 2010-02-17T12:37:17.473 に答える