20

それらの引数を指定または知らずに、デフォルト引数を使用するクラスを前方宣言することは可能ですか?

boost::ptr_list< TYPE >たとえば、Boost ライブラリ全体を特性を含むすべてのファイルにドラッグすることなく、Traits クラスで aを宣言したいと考えています。を宣言したい namespace boost { template<class T> class ptr_list< T >; }のですが、真のクラス宣言と完全に一致しないため、うまくいきません。

template < class T,
    class CloneAllocator = heap_clone_allocator,
    class Allocator = std::allocator<void*>
    >
class ptr_list { ... };

私のオプションは、それと一緒に暮らすこと、またはboost::ptr_list< TYPE, boost::heap_clone_allocator, std::allocator<void*>私の特性クラスで指定することだけですか? (後者を使用する場合は、declareboost::heap_clone_allocatorと includeも転送する必要が<memory>あると思います。)

私は Stroustrup の本、SO、およびその他のインターネットを調べましたが、解決策は見つかりませんでした。通常、人々は STL を含めないことを懸念しており、解決策は「STL ヘッダーを含めるだけ」です。ただし、Boost はより大規模でコンパイラを多用するライブラリであるため、どうしても必要な場合を除き、省略したいと思います。

4

4 に答える 4

16

はい。デフォルトのテンプレート引数は、宣言が互いに競合しない限り、いつでもどこでも指定できます。それらは最終的に、さまざまな宣言から一緒にマージされます。

これでも合法です:

template< class A, class B, class C = long >
class X;

template< class A, class B = int, class C >
class X;

template< class A = short, class B, class C >
class X { };

同様の例が§14.1/10 に示されています。その段落によると、関数のデフォルト引数は同様に動作します。

前方宣言がそれ自体で動作し、すべてをバーフするのではなく、頑張ってください!

于 2010-04-28T05:55:47.443 に答える
9

問題のライブラリが独自の前方宣言ヘッダーを提供しない限り、デフォルト引数でテンプレートを前方宣言できないと思います。これは、デフォルト引数を再指定できないためです (それらが一致していても... gcc は「エラー: デフォルト引数の再定義」を報告します)。

したがって、私の知る限り、解決策は、ライブラリが前方宣言ヘッダー Foo_fwd.h を提供することです。

#ifndef INCLUDED_Foo_fwd_h_
#define INCLUDED_Foo_fwd_h_
template<class T, class U=char> class Foo; // default U=char up here
#endif

Foo.h の完全な実装は次のようになります。

#ifndef INCLUDED_Foo_h_
#define INCLUDED_Foo_h_
#include "Foo_fwd.h"
template<class T, class U> class Foo { /*...*/ }; // note no U=char here
#endif

したがって、コードで Foo_fwd.h も使用できるようになりました...しかし、残念ながら、このアプローチでは元の Foo.h を変更してデフォルトの引数を削除する必要があるため、これはサードパーティのライブラリには対応していません。おそらく、C++0x の乗組員にロビー活動を行って、デフォルトのテンプレート引数の同等の再指定を許可する必要があります。

于 2010-02-22T03:24:31.787 に答える
2

ブースト機能を前方宣言するファシリティを使用するコンパイル ユニットは、機能のブースト部分を実際に使用しない特定のプログラムがある場合を除いて、ブースト ヘッダーを含める必要があります。

確かに、前方宣言することで、そのようなプログラムのブースト ヘッダーを含めないようにすることができます。#ifdefただし、ブースト部分を実際に使用するプログラムには、手動でブースト ヘッダーを含める (または を含める) 必要があります。

将来の Boost リリースでは、さらに多くのデフォルト テンプレート パラメータが追加される可能性があることに注意してください。私はこのルートに反対することをお勧めします。あなたの目標がコンパイル時間を短縮することである場合、私が検討することは、 aを使用#defineして、そのブーストライブラリを使用するコードを無効にする必要があるかどうかを示すことです。このようにして、前方宣言の煩わしさを回避できます。

于 2009-11-24T19:34:30.913 に答える
0

ここでも同じ問題です。しかし、STLで。

私のヘッダーの1つが使用されている場合。std::vector の場合、ヘッダー全体を含める必要があります。この時点から、ソースコードが std::vector をまったく参照していなくても、ヘッダーを含めるたびに、ヘッダーがヘッダーと共に含まれます。このヘッダーを多くの場所に含めると、多くのオーバーパースを意味します。

したがって、 std::vector を前方宣言し、 std::vector* を使用しましたが、デフォルトの引数のためにコードをコンパイルしたくありません。デフォルトの引数をヘッダーに配置すると、デフォルトの引数の尊重により、コンパイラーは stl ヘッダーのコンパイルを拒否します。

この状況で私がやろうとしているのは、std::vector を適応させ、すべてのメソッド呼び出しをそれに転送する独自の Vector クラスを作成することです。おそらく、これで問題が解決する可能性があります。

于 2010-04-28T05:47:58.287 に答える