首页 > 解决方案 > 如何定义依赖于模板参数的 typedef 的 typedef

问题描述

我想制作一个typedef取决于typedef模板参数中存在的 a :

struct foo
{
    using MyType = int;
};

template <typename T = foo>
struct bar
{
    // Pseudo code
    #if T::MyType is defined
        using MyType = T::MyType;
    #else
        using MyType = double;
    #endif
};

有没有办法让它std::conditional在 C++14 中使用或其他东西工作?

标签: c++templatesc++14

解决方案


有,有点sfinae。

template<class, typename Fallback, typename = void>
struct type_or_default {
    using type = Fallback;
};

template<class C, typename F>
struct type_or_default<C, F, std::void_t<typename C::type>> {
    using type = typename C::type;
};

这使用模板元函数公开成员名称的标准约定type,但您可以根据自己的命名需要对其进行调整。这里唯一的非 C++14 位是std::void_t,但是可以在 C++14 中实现等效的东西(它只是不能放入 namespace std)。你在课堂上使用它是这样的:

template <typename T = foo>
struct bar
{
    using type = typename type_or_default<T, double>::type;
};

这里发生的是编译器在选择模板特化时进行模式匹配。如果该类C有一个 member type,那么我们提供的部分专业化将被认为是更专业化的,因此会被选中。否则(如果在检查特化时替换失败),主模板总是可以回退到的。

修补的现场节目。


推荐阅读