编译映射的错误元组按地图类型获取元素

时间:2017-06-14 13:46:35

标签: c++ c++11 templates tuples variadic-templates

我有std::tuplestd::map个容器,由可变参数模板定义,如下所示:

template <typename KeyType, typename... ValueTypes>
class TupleMaps
{
public:
    template<typename T>
    using MapType = std::map<KeyType, T>;

    std::tuple<MapType<ValueTypes>...> member_tuple;
}

我希望通过其值类型从元组中获取适当的映射,我想我可以实现一个成员函数,例如:

MapType<ValueType>& getMap() { std::get<MapType<ValueType>>(member_tuple); }

但在尝试组合

之类的东西时被停止了
TupleMaps<int, float, std::string> maps;
if (maps.getMap<float>().size() !=0) { ... };

编译错误"no matching function for call to get()"

在这种情况下,按类型从元组中提取正确元素的适当方法是什么?

2 个答案:

答案 0 :(得分:2)

public void ConfigureServices(IServiceCollection services) { services.AddMvc().AddJsonOptions(options => { options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc; }); } 被添加到C ++中的C ++ 14中。在C ++ 11中,您只能使用std::get<type>

如果必须使用C ++ 11,则必须使用C ++ 14进行编译或编写自己的std::get<index>版本

答案 1 :(得分:2)

正如NathanOlivier所解释的那样,get<type>(tupleValue)是一个C ++ 14特性。

如果使用C ++ 11编译器,解决方案可以是编写类型特征以选择列表中类型的索引。

以示例

template <typename T, typename T0, typename ... Ts>
struct getI 
 { static constexpr std::size_t value { 1U + getI<T, Ts...>::value }; };

template <typename T, typename ... Ts>
struct getI<T, T, Ts...>
 { static constexpr std::size_t value { 0U }; };

因此,您可以按如下方式编写getMap<type>()方法

   template <typename T>
   MapType<T> & getMap ()
    { return std::get<getI<T, ValueTypes...>::value>(member_tuple); }

   template <typename T>
   MapType<T> const & getMap () const
    { return std::get<getI<T, ValueTypes...>::value>(member_tuple); }

以下是一个完整的工作示例

#include <map>
#include <tuple>
#include <iostream>

template <typename T, typename T0, typename ... Ts>
struct getI 
 { static constexpr std::size_t value { 1U + getI<T, Ts...>::value }; };

template <typename T, typename ... Ts>
struct getI<T, T, Ts...>
 { static constexpr std::size_t value { 0U }; };

template <typename KeyType, typename ... ValueTypes>
struct TupleMaps
 {
   template<typename T>
   using MapType = std::map<KeyType, T>;

   std::tuple<MapType<ValueTypes>...> member_tuple;

   template <typename T>
   MapType<T> & getMap ()
    { return std::get<getI<T, ValueTypes...>::value>(member_tuple); }

   template <typename T>
   MapType<T> const & getMap () const
    { return std::get<getI<T, ValueTypes...>::value>(member_tuple); }
 };

int main ()
 {
   TupleMaps<int, float, std::string> maps;

   std::cout << maps.getMap<float>().size() << std::endl; // print 0

   maps.getMap<float>()[3] = 7.5;

   std::cout << maps.getMap<float>().size() << std::endl; // print 1
 }