0

Visual Studio C++ 2008 をターゲットにする

状況: 多数のパラメーターを持つテンプレート クラスがあり、多くはデフォルトです。

template <typename A, typename B = b, typename C = c>
struct Outer
{
    typedef typename A typeA;
    typedef typename B typeB;
    typedef typename C typeC;
};

これまでのところとても良い。今、たくさんのOuters で構成されるユーザー定義型があります。この状況では、タイプ A と B は既知ですが、C は不明です。

これに対処するための私の最初のアプローチは、新しいユーザー タイプ内で A と B を複製することでした。

template<typename A, typename B>
struct UserDefinedType {
    Outer<A, B, int> AnIntOuter;
    Outer<A, B, float> AFloatOuter;
};

これは機能しますが、すぐに飽きてしまいます。(および実際のコードからの他の複雑さ)。私は考えていました...デフォルト値として渡されたテンプレートパラメーターを使用して新しい内部クラスを作成しないので、これを試してみました:

template<typename A, typename B>
struct AnotherUserDefinedType {
    template<typename CC, typename AA = A, typename BB = B>
    struct Inner : public Outer<AA, BB, CC> {};

    Inner<int> AnIntInner;
    Inner<float> AFloatInner;
};

これをコンパイルしようとすると、メンバーの宣言 (この場合は AnIntInner) に関連付けられているように見える「テンプレート引数が少なすぎます」というエラーが表示されます。

私が知りたいこと: これ (外部クラスのテンプレート パラメーターを内部クラスの既定のテンプレート パラメーターとして使用する) はリモートでも可能ですか?

可能であれば、私の構成が間違っているのでしょうか、それともMSVC ++ 2008 に関する既知の問題はありますか? または、もちろん、私のコードにも何か問題がある場合は、

アップデート

ああ、アシストされた 20/20 後知恵は常に素晴らしいです。私の質問と私が本当に必要としていた答えには、少なくともハットトリックの問題があることがわかりました。

まず、@DyP は SSCCE の呼び出しで正しく、完全な例 (難読化された C++ コンテストに参加していた場合に 1 行) を 5 行しか欠落していませんでしたが、自分のコードを見て、「これは正しいように見えるので、私が試した新しいことが問題を引き起こしているに違いありません」そして、私は自分の例を作成しませんでした. コンパイラが発行したテンプレート エラー メッセージ interpreting-fu に取り組む必要があります (そうそう、そして as-u-me-ing 部分...)。

ただし、@ nickieが丁寧に言っていないように、その構成は冗長です。デフォルトのテンプレート パラメーターには適切な場所がありますが、ここでは必要ありません。内側のクラスには、外側のクラスで使用されるテンプレート パラメーターが表示されます。「無料」にするために必要なパラメーターのみをテンプレート化する方がはるかに優れています。そもそも技術的には間違っていなかったとしても、@ nickieは質問に完全に答えたと思うので、@ nickieの答えにチェックマークが付いています。

しかし、それで終わりではありません。@DyP は、いくつかのテンプレート パラメーターをカリー化したいという私の本当の問題を正しく直感しました (ここで外側のテンプレート パラメーターを再コピーすると、実際のカリー化として厳密にバインドするのではなく、テンプレート パラメーターを変更するオプションが必要な場合に使用されます)。そうです(まあ、カリー化されたパラメーターはファンクターかもしれません...しかし、私は脱線します))。クラスを拡張するのではなく、型が必要でした。継承の問題は、いくつかのオーバーライド、つまり operator=() を壊すことです。

ですから、私たち 3 人全員の入力を組み合わせて、この構造が最終的に使用したものです。

template<typename A, typename B>
struct FinalUserDefinedType {
    template<typename C, typename AWithDefault = A>
    struct CurryType {
        typedef Outer<AWithDefault, B, C> type;
    };

    CurryType<int>::type AnIntOuter;
    CurryType<float>::type AFloatOuter;
    CurryType<double, int>::type AnOverriddenDefault;
};

更新 2

私を一度だまして、私を恥じて、二度だまして、私を9番目のサークルに送ってください。

繰り返しますが、私が示した例はコンパイルしませんでした。私の実際のコード(@DyPはこれをもう一度キャッチしました...)から除外すると、例は次のようになります。

template<typename A, typename B>
struct FinalUserDefinedType {
    template<typename C, typename AWithDefault = A>
    struct CurryType {
        typedef Outer<AWithDefault, B, C> type;
    };

    typename CurryType<int>::type AnIntOuter;
    typename CurryType<float>::type AFloatOuter;
    typename CurryType<double, int>::type AnOverriddenDefault;
};

バーチャルボーナスポイントについて、AnIntOuterを使わずに 等を宣言することはできtypenameますか?

4

1 に答える 1