4

事前に注意してください。この質問は、実際よりもはるかに明白に思えます。

任意の具象クラスまたはテンプレート クラスをテンプレート パラメーターとして受け入れることができるテンプレートを作成したいと考えています。渡された T がテンプレート化されているかどうかを知らなければ、その使用方法がわからないため、これは役に立たないように思えるかもしれません。これが必要な理由は、定義のない一般的なテンプレートを宣言して、ユーザーが特化できるようにするためです。ユーザーはそれを専門に扱っているため、自分が扱っている型について常に知っています。ただし、ユーザーは、最初に宣言されていないテンプレートを特殊化することはできません。

あなたはこれを行うことができます:

template<class T>
class myclass;

ただし、テンプレート化された T を渡すと、それは機能しません。たとえば、機能しmyclass<std::vector>ません。それで、これを試します:

template<class T>
class myclass;

template<template<class> T>
class myclass;

これは正しい方法かもしれませんが、クラス テンプレートをオーバーロードできないため、そのままでは機能しません。それでは、次のような関数テンプレートに切り替えましょう。

template<class T>
void myfunc();

template<template<class> T>
void myfunc();

いいですね、これで終わりですよね?テンプレートのテンプレート パラメータに指定されたパラメータの数が異なる可能性があるため、それも考慮する必要があります。

template<class T>
void myfunc();

template<template<class> T>
void myfunc();

template<template<class, class> T>
void myfunc();

template<template<class, class, class> T>
void myfunc();

// etc.

醜いですが、Boost Preprocessor Libraryがこのコードを生成してくれます (C++0x では可変個引数テンプレートのサポートが追加されるため、この醜さは一時的なものです)。しかし、私たちはまだケースを忘れています! T のパラメーターの 1 つがクラスではなく、定数の整数である場合はどうなるでしょうか。それをサポートしようとしましょう:

template<class T>
void myfunc();

template<template<class> T>
void myfunc();

template<template<class, class> T>
void myfunc();

template<template<class, class, class> T>
void myfunc();

// etc.

template<template<class> T>
void myfunc();

template<template<class, int> T>
void myfunc();

template<template<int, class> T>
void myfunc();

template<template<int, class, class> T>
void myfunc();

template<template<class, int, class> T>
void myfunc();

template<template<class, class, int> T>
void myfunc();

// etc.

ええとああ。任意の定数型を任意の数でテンプレートに渡すことができ、クラス パラメータと混合できるとすれば、KABLOOEY の組み合わせ爆発です。さらに難しいことに、T のパラメーターのいずれか自体がテンプレートである場合はどうなるでしょうか。

4

3 に答える 3

3

boost::mpl は次のようなことを行います (これは、引数をバインドするという彼らの考えです)。ただし、使用するなど、機能させるには多くの仮定を行う必要があります。

template <class T> foo { }; typedef foo< int_<4> > my_foo_4;

それ以外の

template <int T> foo { }; typedef foo<4> my_foo_4;

int、char、bool などのすべての組み合わせに対してオーバーロードを提供する必要はありません。

boost::mpl アプローチよりも効果的なものは考えられません。一般に、どのアプローチも多くの問題を抱えていると思います。クラス テンプレートは型ではなく、そのように型システムに組み込むことはできません (boost::mpl はそれを新しい型を作成する関数として扱います。より一般的には、「MetaFunction」を作成するために使用されます)。 . 可変個引数テンプレートがテンプレート テンプレート パラメーターに影響を与えるかどうかさえわかりません (興味深い質問ですが)。

于 2009-06-02T15:44:41.010 に答える
1

解決策は、テンプレートの特殊化ではなく、関数のオーバーロードを使用することです! コンパイル時間は改善され、制約はなくなります...

どのテンプレートも、使用後に最も近いグローバル スコープでインスタンス化されたと見なされることに注意してください。これは、これが機能することを意味します。

template <class T>
int f(const T& t)
{
  return g(t);
} 

int g(int a)
{
  return a+1;
}

int main()
{
   return f(5);
}

gご覧のとおり、関数が の後に定義されていても機能しfます。これは、関数を使用する任意のテンプレートを定義できることを意味します。ユーザーがテンプレートを使用する前に関数を定義する限り、問題はありません。C++ はそれを見つけます。

関数にはテンプレートの特殊化が存在しないことも忘れないでください。同じ名前の関数が多数存在する場合、C++ はテンプレートの特殊化ではなく、常にオーバーロードを予期します。

つまり、関数をあたかも存在するかのように使用し、ユーザーがテンプレートを使用する前に関数を定義することを期待するのが最善の解決策です。

于 2009-06-02T15:41:06.377 に答える
0
template <class T> class myclass;

template <> class myclass<int>{};
template <> class myclass<std::vector<int>>{};
template <> class myclass<std::vector<std::vector<int> > >{};

これは、あなたの望むことですか?

于 2009-06-02T16:25:10.990 に答える