c++ - 根据模板类型选择类模板的成员类型?

标签 c++ templates sfinae

我有一个包含某种类型成员的类模板。该类型是根据实例化模板时提供的类型确定的。它使用默认值(在下面的示例中为 double),除非该类提供了覆盖。用作模板类型的类可以提供此覆盖 type (此处“Two”提供覆盖类型“int”)。如果某个类提供了覆盖,则仅当该类还设置了 UseOverride 标志时才应使用覆盖。如果标志不存在或为假,则应使用默认的“double”。

问题是,如果模板类型未提供“类型”,则编译器会在下面的代码中给出错误。我怀疑我需要在这里使用 SFINAE,但即使在下午的大部分时间里困惑和浏览相关问题之后,仍无法找到合适的方法。

如何定义 EventType 模板以使其按预期工作?我想保留EventType<T>语法。

#include <iostream>

struct One {
    //This type is ignored, and double is used, because UseOverride = true is not specified:
    using type = short;
};
struct Two {
    static constexpr bool UseOverride = true;
    using type = int;
};

struct Three {
    static constexpr bool UseOverride = false;
    //I don't want the compiler to complain that "type" is not available here (because it should default to double anyhow since 
    //the class instructs not to use the override). But compile does generate error. 
    //How to avoid this?
};

template <typename T, typename = void>
struct overrideInfoProvided : std::false_type {};
template <typename T>
struct overrideInfoProvided<T, decltype((void)T::UseOverride, void())> : std::true_type {};

template <typename T>
constexpr bool Override()
{
    if constexpr (overrideInfoProvided<T>::value)
    {
        return T::UseOverride;
    }
    return false;
}

template<class T>
using EventType = typename std::conditional_t<Override<T>(), typename T::type, double>;


template <class T>
struct Test
{
    typename EventType<T> member;
    Test()
    {
        std::cout << member << std::endl;
    }
};

int main()
{
    Test<One>();
    Test<Two>();   
    //Gives error:
    //Test<Three>();// `type': is not a member of any direct or indirect base class of `three'; 
}

最佳答案

I don't want the compiler to complain that "type" is not available here (because it should default to double anyhow since the class instructs not to use the override). But compiler does generate error. How to avoid this?

只需使用以下 type_identity 推迟对 ::type 的访问即可助手:

template <typename T>
struct type_identity { using type = T; };

template <typename T>
using EventType = typename std::conditional_t<Override<T>()
                                            , T
                                            , type_identity<double>>::type;
//                                            ~~~~~~~~~~~~^        

DEMO

关于c++ - 根据模板类型选择类模板的成员类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62198304/

相关文章:

c++ - 使用虚拟派生方法返回不同的迭代器

c++ - 在类模板实例化中为某些参数显式使用默认值

c# - 从模板创建 PDF

c++ - 函数模板

c++ - 如何使用 sfinae 选择构造函数?

c++ - 为泛型类型重载函数与为给定类型及其子类型重载函数

c++ - 基于模板类型指针性的条件函数行为

c++ - 大象号到底是什么?

c++ - 如何使用 OPENCV 获得最小外接圆?

c++ - 声明的允许使用上下文