C ++:"推断"依赖类型的模板类型

时间:2017-03-15 19:35:23

标签: c++ templates

我有一个班级:

class MyClass{
    enum Choices : int
    {
        First,
        Last
    };
    template<MyClass::Choices choice>
    void bar(...);
};

我希望能够在客户端代码中对choice进行bar()模板化调用。既然我不希望客户端代码负责管理MyClass个实例,我想添加另一个层来负责这个,所以我会:

{
   t = new T();
   t.bar<choice>();
};

在函数内部。

理想情况下,我希望能够调用此图层,让我们将其称为foo(),如下所示:

foo<MyClass::Choices::One>(...);

这可能吗?这就是我尝试过并且遇到错误:

template<typename T>
template<T::Choices choice>
void foo(){
   t = new T();
   t.bar<choice>();
};

1 个答案:

答案 0 :(得分:1)

我相信这是使用特征的最佳方法:

#include <iostream>
#include <type_traits>

template <typename T>
struct choice_traits;

class MyClass{
public:
    enum Choices : int
    {
        First,
        Last
    };
    template<MyClass::Choices choice>
    void bar(...) {}
};

template <>
struct choice_traits<MyClass::Choices>
{
    using parent = MyClass;
};

template <MyClass::Choices C>
using choice_const = std::integral_constant<MyClass::Choices, C>;

template <typename C, C value>
void foo(std::integral_constant<C, value>)
{
    using T = typename choice_traits<C>::parent;

    T* t = new T();

    t->template bar<value>();
}

int main()
{
    foo(choice_const<MyClass::Choices::First>());

    return EXIT_SUCCESS;
}

您需要为每个具有枚举选项的容器类专门化choice_traits。我还创建了一个帮助器choice_const,以避免直接使用std::integral_constant

如果有更多信息可以改进,但根据你的解释可以做到这一点。