使用外部类的模板参数设置内部模板类的默认模板参数

时间:2013-09-04 20:45:58

标签: c++ templates visual-c++

定位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;
};

到目前为止一切都很好。现在,我有一个用户定义的类型,包含很多很多Outer个。在这种情况下,类型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)。

我想知道的是:这是否(使用外部类的模板参数作为内部类的默认模板参数)是否可以远程实现?

如果 IS 可能,我的构造是错误的还是MSVC ++ 2008存在已知问题?或者,当然,如果我的代码中可能还有其他错误

更新

啊,事后协助20/20事后总是很棒。我看到我至少有一个问题的帽子戏法和我真正需要的答案。

首先,@ DyP在呼唤SSCCE时是正确的,即使我只缺少五行作为一个完整的例子(如果我进入混淆的C ++比赛,一个)我查看了我的代码并说“这看起来正确,所以我尝试过的新事物必然会导致问题“我甚至没有建立自己的例子。我需要处理我的编译器发布的模板错误信息interpreting-fu(哦,是的,以及ass-u-me-ing部分......)。

然而,正如@nickie礼貌地没有说的那样,这种结构是多余的。默认模板参数有它们的位置,但在这里,它甚至不需要。内部类具有外部类中使用的模板参数的可见性。最好只模板化我需要“免费”的参数。我认为@nickie完美地回答了这个问题,尽管从技术上讲我一开始并没有错,所以@ nickie的回答得到了勾选标记。

但这并不会结束。 @DyP正确地直觉我真正的问题是我想要讨论一些模板参数(在这里重新复制外部模板参数确实有它的用途我们想要改变模板参数的选项,而不是将它紧密绑定为真正的currying (好吧,咖喱参数可能是一个算子...但我离题了))。我只需要类型,而不是扩展类。继承的问题在于它打破了一些覆盖,即operator =()。

因此,结合我们三个人的输入,这个结构就是我最终使用的

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

欺骗我一次,羞辱,欺骗我两次,把我送到第九圈。

再一次,我没有编译我给出的例子。从我的真实代码中消失(@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等?

1 个答案:

答案 0 :(得分:3)

我认为这是做你想做的事的正确方法(如果我理解了这是正确的):

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

template<typename A, typename B>
struct AnotherUserDefinedType {
    template<typename C>
    struct Inner : public Outer<A, B, C> {};

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