模板化字段引用模板参数可以作为第一个模板参数传递吗?

时间:2019-07-03 22:08:18

标签: c++ templates

我在template <class Base> class foo {}中使用以下方法:

template <
    typename V,
    template <class, class> class Map,
    Map<std::string, V> Base::*Field,
    std::size_t Len
>
constexpr const foo<Base> s(char const (&section_name)[Len]) const {
    #pragma unused(section_name)
    return *this;
}

我的目标是能够简单地通过以下方式调用它:

struct my_struct {
    std::map<std::string, int> section;
    constexpr auto bar = foo<my_struct>()
        .s<&my_struct::section>("hi");
};

这可能是通过专门化实现的吗?我不能全神贯注于如何使它甚至编译,因为由于模板化的Map类型首先出现在声明中,因此我目前无法传递成员指针,这使我在clang上获得了以下内容: / p>

  

注释:候选模板被忽略:模板参数“ Map”的显式指定无效参数

我似乎也无法使专业化的神奇咒语起作用,

template <auto FieldType, std::size_t Len>
constexpr const foo<Base> s(char const (&section_name)[Len]) const;

template <
    template <class, class> class Map,
    typename SecType,
    Map<std::string, SecType> Base::*Field,
    std::size_t Len
>
constexpr const foo<Base> s<Field, Len>(char const (&section_name)[Len]) const {

}

给出

  

错误:不允许功能模板部分专业化

我什至有可能吗?值得一提的是c ++ 14及更高版本。

1 个答案:

答案 0 :(得分:0)

对于C ++ 17之前的解决方案,您可以将成员指针放入% plot data p = [0 0 1 1; 0 1 0 1]; t = [0 0 0 1]; plotpv(p,t) % change colors ax = gca for i = allchild(ax)' switch i.Marker case '+' i.MarkerEdgeColor = 'k'; case 'o' i.MarkerEdgeColor = 'r'; end end 中。要确保地图的键类型是std::integral_constant,请使用类型推导从指针获取成员类型,并将其键类型与std::string进行比较:

std::string

您在编辑中遇到的错误是由于无法部分专门化功能模板。幸运的是,您可以扩展上面我的答案中的代码,以便您可以基于带有标签分派的键类型重载:

template<class T, class C>
T get_member_type(T C::*);

template<class Base>
struct foo{
  template<class I, std::size_t Len>
  constexpr const foo<Base> s(I, char const (&section_name)[Len]) const {
    using M=decltype(get_member_type(I::value));
    static_assert(std::is_same<typename M::key_type, std::string>{});
    return *this;
  }
};

#define CONST(e) std::integral_constant<decltype(e), e>

struct my_struct {
  std::map<std::string, int> section;
  constexpr static auto bar = foo<my_struct>().s(CONST(&my_struct::section){}, "hi");
};