1

メタプログラミング手法を使用するコードの一部では、他の場所に転送されて後で変換されるテンプレート化された引数を使用するため、これらのクラスの一部のインスタンスを実際に作成することはありません。

特に、std::vector<T>Tにベクトルに含まれるセマンティクスがない場合に使用します。実際には、を作成しますがstd::vector<shared_ptr<T> >

コードは次のようになります。

class Bar : noncopyable
{ 
    // whatever
};

class Foo : public FooInterface
{
  public:
    explicit Foo( std::vector< shared_ptr<Bar> > );
};

typedef Builder1Param< FooInterface, Foo, std::vector<Bar> > FooBuilder;

FooBuilderは、巧妙なメタプログラミング手法により、をではvector<shared_ptr<Bar> >なくFooに渡すことを認識していvector<Bar>ます。問題は、Barはコピーできないため、ベクトルに対して無効な型であるということです。

これで、コードはこれを使用したすべてのコンパイラで正常にコンパイルされますが、有効なC ++であるかどうかを知りたいです(C ++ 11以降でも引き続き有効です)。

私はおそらく、バーが実際には抽象的である可能性があることを追加する必要があります(そしてしばしばそうなるでしょう)。目的は、パラメーターがこれらのコレクションであることを示すことです(ある意味では、Java / C#参照のスタイルで)。

4

2 に答える 2

1

タイプをインスタンス化しない限り、技術的には問題ありません。たとえば、不完全なタイプの場合と同じです。

しかし、それは恐ろしいデザインです。

そのすべてのゆがみは、パラメータを渡すだけでなく、より多くのキー押下を使用して誤解を招くようなものを書くことを可能にします。

そのデザインを再考します。

例:

typedef Builder1Param< FooInterface, Foo, std::vector, Bar > FooBuilder;

テンプレート定義部分についてstd::vectorは、ここにテンプレートテンプレートパラメータがあります。

于 2012-09-14T11:26:31.627 に答える
0

の要件を満たさないstd::vector<Bar>プログラムで使用すると、未定義の動作が生成されます。これは、C++11 標準の 17.6.4.8 [res.on.functions] からのものです。Barstd::vector

場合によっては (置換関数、ハンドラー関数、標準ライブラリ テンプレート コンポーネントのインスタンス化に使用される型の操作)、C ++ 標準ライブラリは C ++ プログラムによって提供されるコンポーネントに依存します。これらのコンポーネントが要件を満たさない場合、標準は実装に要件を課しません。

特に、次の場合の効果は定義されていません。

...

— テンプレート コンポーネントをインスタンス化するときにテンプレート引数として使用される型の場合、型に対する操作が該当する要件の節 (17.6.3.5、23.2、24.2、26.2) のセマンティクスを実装しない場合。

...

— そのコンポーネントに対して特に許可されていない限り、テンプレート コンポーネントをインスタンス化するときに、不完全型 (3.9) がテンプレート引数として使用された場合。

于 2012-09-14T16:00:59.883 に答える