面向 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
s 组成的用户定义类型。在这种情况下,类型 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++ 竞赛的话)我查看了我的代码并说“这看起来正确,所以它我尝试过的新事物一定会导致问题”,我什至没有建立自己的例子。我需要处理我的编译器发出的模板错误消息解释-fu(哦,是的,还有 ass-u-me-ing 部分......)。
然而,正如@nickie 礼貌地没有说的那样,这个结构是多余的。默认模板参数有它们的位置,但在这里,它甚至不需要。内部类可以看到外部类中使用的模板参数。最好只模板化我需要“免费”的参数。我认为@nickie 完美地回答了这个问题,尽管从技术上讲我一开始并没有错,所以@nickie 的回答得到了复选标记。
但这并没有结束。@DyP 正确地直觉了我真正的问题,那就是我想对一些模板参数进行柯里化(在这里重新复制外部模板参数确实有它的用途,我们希望选择改变模板参数而不是将其紧密绑定为真正的柯里化确实(好吧,咖喱参数可能是一个仿函数......但我离题了))。我只需要类型,而不是扩展类。继承的问题在于它破坏了一些覆盖,即 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
不使用的情况下声明 , et al typename
?