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

标签 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)。

我想知道的是:这(使用外部类的模板参数作为内部类的默认模板参数)甚至可能吗?

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

更新

啊,辅助 20/20 后见之明总是很棒。我发现我的问题和我真正需要的答案至少上演了帽子戏法。

首先,@DyP 呼吁 SSCCE 是正确的,尽管我只缺少五行完整示例(如果我正在参加混淆的 C++ 竞赛)我看过我的代码并说“这看起来不错,所以一定是我尝试的新事物导致了问题”,我什至没有建立自己的例子。我需要处理我的编译器发出的模板错误消息 interpreting-fu(哦,是的,还有 ass-u-me-ing 部分......)。

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

但这并没有结束一切。 @DyP 正确地直觉到我真正的问题是我想柯里化(Currying)一些模板参数(在这里重新复制外部模板参数确实有它的用途,我们希望选择改变模板参数而不是将其紧密绑定(bind)为真正的柯里化(Currying)确实(好吧,柯里化(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;
};

对于虚拟奖励积分,是否可以在不使用 typename 的情况下声明 AnIntOuter 等?

最佳答案

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

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

关于c++ - 使用外部类的模板参数设置内部模板类的默认模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18623460/

相关文章:

c++ - mysql 重新连接 C++

c++ - 使用可变数量的模板化参数访问模板化类的成员

c++ - 类模板特化与模板

c++ - MSVC 中可能的编译器错误

c++ - 如何让 CMake 基于 GCC 版本通过 std=c++14/c++1y 或 c++17/c++1z?

c++ - 如何实例化派生类数组

python - 谷歌应用引擎: post a group of entities at one time

visual-c++ - 将定义的符号与预编译头相乘?

templates - 指定了多个复制构造函数

c++ - Qt 在 Linux 上不显示 PNG 图像