【问题标题】:Use std::map with std::any as value type使用 std::map 和 std::any 作为值类型
【发布时间】:2019-06-23 17:27:02
【问题描述】:

我希望类 Config 能够在字符串键中存储任何值。为此目的,似乎 std::map 适合。不幸的是,这没有编译。

看起来std::is_copy_constructible<std::tuple<const std::any&>> trait 失败了。我该如何克服呢? 请在https://github.com/marchevskys/VisualEngine找到源代码。

代码思路同下,

#include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <any>
#include <map>
//#include <glm/glm.hpp>

//using vec3d = glm::vec<3, double, glm::highp>;

class Config {
public:
   static Config* get() {
    static Config config;
    return &config;
    }

   enum class Option : int {
      ImGuiEnabled = 0x0,   // bool
      ShipPosition = 0x1    // glm::vec3
   };

   using cb_function = std::function<void(std::any)>;

   bool is_option_available(Option option) const { return m_config.at(option).has_value(); }
   std::any get_option(Option option) const { return m_config.at(option); }
   void set_option_value(Option option, const std::any& value) { m_config.insert_or_assign(option, value); }
private:
   Config() {/* m_config[Option::ShipPosition] = vec3d({ 0., 0., 0. }); */} 
   ~Config() = default;
   std::map<Option, std::any> m_config;
};

int main()
{
    Config::get()->set_option_value(Config::Option::ImGuiEnabled, false);
    bool isImGuiEnabled = std::any_cast<bool>(Config::get()->get_option(Config::Option::ImGuiEnabled));
    std::cout << std::boolalpha << "ImGuiEnabled ? " << isImGuiEnabled << std::endl;
}

在 MS Visual Studio 上编译,并且使用早于 9.1.0 g++,但不会在 g++ 9.1.0 上编译。

你会得到同样的错误:

#include <type_traits>
#include <tuple>
#include <any>

int main()
{
  bool b = std::is_copy_constructible< std::tuple<const std::any&> >::value );
  (void)b;
}

【问题讨论】:

  • 尝试用-stdlib=libc++标志编译
  • 你需要显示你的编译命令和你的编译错误。
  • 感谢您的回答,我更改了代码,因此不使用 std::any 而是使用 std::variant。
  • 您的问题可能是任何问题,包括您忘记包含头文件。需要minimal reproducible example 来解决您的问题。
  • 使用 gcc 9.1.0 为我编译的代码(经过一些添加,因为问题中的代码不完整)。所以我们肯定需要 1) 足够的代码来自己编译; 2)用于编译的命令行;和 3) 确切的错误消息(无论您对错误消息的解释是否)。

标签: c++ c++17 stdmap glm-math stdany


【解决方案1】:

当我们询问“可以复制std::tuple&lt;const std::any&amp;&gt;”时触发了奇怪的错误。

这最终会破坏,因为它被复制最终会检查“可以复制std::tuple&lt;const std::any&amp;&gt;”作为中间步骤。

这是因为其中一个中间步骤涉及检查您是否可以从std::tuple&lt;std::any const&amp;&gt; 制作std::any const&amp;,然后询问您是否可以复制std::tuple&lt;std::any const&amp;&gt;,它询问您是否可以制作std::any const&amp;来自std::tuple&lt;std::any const&amp;&gt;

所有这些似乎都是由映射中的代码触发的,该代码将第二个参数捆绑在std::tuple 中,然后尝试用它来构建std::any。但它尝试 both 使用参数构造 std::any 将元组作为一个整体。

这似乎是 GCC 标准库中的一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-06
    • 2012-10-04
    • 2018-11-19
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    相关资源
    最近更新 更多