gpt4 book ai didi

c++ - 如果类成员 typedef 不存在,则模板特化使用默认类型

转载 作者:IT老高 更新时间:2023-10-28 22:27:06 30 4
gpt4 key购买 nike

我正在尝试编写使用模板参数的成员 typedef 的代码,但如果模板参数没有该 typedef,我想提供默认类型。我试过的一个简化的例子是这样的:

struct DefaultType    { DefaultType()    { printf("Default ");    } };
struct NonDefaultType { NonDefaultType() { printf("NonDefault "); } };

struct A {};
struct B { typedef NonDefaultType Type; };

template<typename T, typename Enable = void> struct Get_Type {
typedef DefaultType Type;
};
template<typename T> struct Get_Type< T, typename T::Type > {
typedef typename T::Type Type;
};

int main()
{
Get_Type<A>::Type test1;
Get_Type<B>::Type test2;
}

我希望这会打印“Default NonDefault”,但它会打印“Default Default”。我的期望是 main() 中的第二行应该匹配 Get_Type 的专用版本,因为 B::Type 存在。但是,这不会发生。

谁能解释这里发生了什么以及如何解决它,或以其他方式实现相同目标?

谢谢。

编辑:

Georg 提供了另一种方法,但我仍然很好奇为什么这不起作用。根据 boost enable_if 文档,一种针对不同类型专门化模板的方法如下:

template <class T, class Enable = void> 
class A { ... };

template <class T>
class A<T, typename enable_if<is_integral<T> >::type> { ... };

template <class T>
class A<T, typename enable_if<is_float<T> >::type> { ... };

这是因为 enable_if< true > 有 type 作为 typedef,但 enable_if< false > 没有。

我不明白这与我的版本有何不同,我只是直接使用 T::Type 而不是使用 enable_if。如果存在 T::Type 与上面示例中的 enable_if< true >::type 是否相同并导致选择特化?如果 T::Type 不存在,那岂不是和 enable_if< false >::type not existing 一样,导致上面例子中选择了默认版本?

最佳答案

回答您的添加 - 您的特化参数传递成员 typedef 并期望它产生 void作为类型。这没有什么神奇之处——它只是使用一个默认参数。让我们看看它是如何工作的。如果你说Get_Type<Foo>::type ,编译器使用默认参数 Enable ,即 void ,类型名称变为 Get_Type<Foo, void>::type .现在,编译器检查是否有任何偏特化匹配。

你的部分特化的参数列表<T, typename T::Type>从原始参数列表中推导出 <Foo, void> .这将推导出 TFoo然后替换为 Foo进入特化的第二个参数,产生 <Foo, NonDefaultType> 的最终结果为您的部分特化。但是,这与原始参数列表不匹配 <Foo, void>完全没有!

您需要一种方法来产生 void键入,如下所示:

template<typename T>
struct tovoid { typedef void type; };

template<typename T, typename Enable = void> struct Get_Type {
typedef DefaultType Type;
};
template<typename T>
struct Get_Type< T, typename tovoid<typename T::Type>::type > {
typedef typename T::Type Type;
};

现在这将像您期望的那样工作。使用 MPL,您可以使用 always而不是 tovoid

typename apply< always<void>, typename T::type >::type

关于c++ - 如果类成员 typedef 不存在,则模板特化使用默认类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3008571/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com