この質問には、(間接的に) 式テンプレートが関係しているため、C++ テンプレート メタプログラミングの知識が必要です。式テンプレートに関する直接的な質問ではなく、C++ 型の計算が含まれるため、間接的に言います。それが何かわからない場合は、この質問に答えないでください。
十分な背景情報なしに質問を出すことを避けるために、私が解決しようとしている一般的な問題について少し詳しく説明してから、より具体的な部分に進みます。
Integer
ユーザーが s と同じように計算できる s を提供するライブラリがあるとしますint
。Integer
さらに、からを構築することが可能int
です。と同じように:
Integer<int> i(2);
内部的には、私のInteger
クラスはクラス テンプレートです:
template<class T>
class Integer {
// cut out
};
したがって、好きな整数型で定義できます。
API を変更せずに、ライブラリを変更して、Integer
から構築された場合int
、別の型 (たとえば ) で内部的に表現する必要があるようにしたいと思いますIntegerLit
。この理由は、 のインスタンスが(ベース ポインター + 個別のデータによって記述される一般的なオブジェクトとしてではなく、引数として関数に渡すことができる)Integer
から作成されたことを知っていると、一部の計算を高速化できるためです。コメント。)int
int
から構築する場合は型が異なることが不可欠です。これはint
、コンパイラが an から構築されたかどうかに応じて異なるコード パスを使用する必要があるためですint
。ランタイム データ フラグを使用してこれを行うことはできません。(要するに、コンパイラは、int
タイプに応じて、または上記のより一般的なタイプのオブジェクトを取る関数を生成します。)
これを言うと、私は問題に遭遇します:使用が次のようなことをするとき:
Integer<int> a,b(2);
a = b + b;
ここa
には、一般的なものInteger
とb
専門的なものがありIntegerLit
ます。Integer
ただし、私の問題は、ユーザーが変数を定義するためにまったく同じ型を自由に使用できるため、これを C++ で表現する方法です。
型をポリモーフィックにする、つまり派生元は機能IntegerLit
しInteger
ません。一瞬元気そうです。Integer
ただし、ユーザーは(基本クラス) のインスタンスを作成するため、それは基本クラスであるため、コンパイラーは式ツリーに固執します (これが、式テンプレートが問題に関与する理由です)。したがって、この 2 つのケースを区別することはできません。動的キャストで RTTI チェックを行うことは、その時点で私が望んでいることではありません。
より有望なのは、リテラルテンプレートパラメーターbool lit
を型に追加して、それがから構築されたint
かどうかを示しているようです。ポイントは、リテラルでないものには変換規則を指定せず、他の場合には指定することです。
しかし、私はそれを機能させることができません。次のコードは、int
. true
それ以外の場合、 の値としてInteger が指定されていないため、失敗しますlit
。そのため、コンパイラは変換規則を持たないデフォルトの実装を検索します。API を変更するオプションではなく、Integer<int,true>
から構築するときに記述する必要がありint
ます。
template<class T,bool lit=false>
class Integer
{
public:
Integer() {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
T F;
};
template<>
template<class T>
class Integer<T,true>
{
public:
Integer(int i) {
std::cout << __PRETTY_FUNCTION__ << "\n";
}
T F;
};
このようなことが C++ で可能かどうか疑問に思い始めています。
ここで役立つ C++11 の新機能はありますか?