针对 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/