2

次のプログラムは正常に実行されます。

struct M; // forward declare so compiler will recognize this type
struct N;

template< typename J > struct B { template< typename U > void Func1(); };

template<> template<> void B< M >::Func1< M >() {}
template<> template<> void B< N >::Func1< N >() {}
template<> template<> void B< M >::Func1< N >() {} // illegal specialization for this app

template< typename J > struct C { template< typename U > void Func2(); };

template<> template<> void C< M >::Func2< M >() {}
template<> template<> void C< N >::Func2< N >() {}

template< typename G > struct H { G g; };

int main()
{
  H< B< M > > hbm;
  hbm.g.Func1< M >(); // ok
  hbm.g.Func1< N >(); // compiles and runs, but uses a semantically illegal specialization for this app

  H< B< N > > hbn;
  hbn.g.Func1< N >(); // ok

  H< C< M > > hcm;
  hcm.g.Func2< M >(); // ok

  H< C< N > > hcn;
  hcn.g.Func2< N >(); // ok

  return 0;
}

構造体 B と C をコンパイル時に明示的に宣言し、アプリにとって意味のある特殊化のみを許可することが重要です。

しかし、上記のコードに見られるように、下流の開発者 (いつか!) が、意味的に意味をなさない構文的に正しいパターンを作成できる可能性があります。具体的には、アプリは、クラスと関数の型が等しい型の使用方法しか認識していません。残りは無意味です。

これは、SFINAE、Constraints、Concepts などの新しい C++17+ 機能の 1 つのケースのようです。私はこれらについて読んでいますが、その選択をする判断はまだありません. Alternatives の下の cppreference では、コンパイラが機能している場合 (私は VS2015 を使用しています)、SFINAE の代わりに Concepts を提案しています。

型名 J が型名 U と同じになるように制約するにはどうすればよいでしょうか?

4

1 に答える 1