【问题标题】:compile error tuple of maps getting elements by map type编译按地图类型获取元素的地图错误元组
【发布时间】:2017-06-14 13:46:35
【问题描述】:

我有一个 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()".

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

【问题讨论】:

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


【解决方案1】:

正如 NathanOlivier 所解释的,get&lt;type&gt;(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&lt;type&gt;()方法如下

   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
 }

【讨论】:

    【解决方案2】:

    std::get&lt;type&gt; 在 C++14 中被添加到 C++。在 C++11 中,您只能使用 std::get&lt;index&gt;

    如果你必须使用 C++11,你要么必须在启用 C++14 的情况下进行编译,要么编写自己的 get 版本

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      相关资源
      最近更新 更多