使用 std::map 和 std::any 作为值类型
Use std::map with std::any as value type
我希望 class Config 能够在字符串键中存储任何值。为此目的,似乎 std::map 适合。不幸的是,这不是编译。
看起来 std::is_copy_constructible<std::tuple<const std::any&>>
特征失败了。我怎样才能克服它?
请在 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;
}
当我们询问 "can a std::tuple<const std::any&>
be copied" 时触发了奇怪的错误。
这最终会中断,因为它被复制最终会检查 "can std::tuple<const std::any&>
be copied" 作为中间步骤。
这是因为其中一个中间步骤涉及检查您是否可以从 std::tuple<std::any const&>
制作 std::any const&
,这反过来会询问您是否可以复制 std::tuple<std::any const&>
,这会询问如果你能从 std::tuple<std::any const&>
中得到 std::any const&
,等等
所有这些似乎都是由映射中的代码触发的,该代码将第二个参数捆绑在 std::tuple
中,然后尝试 emplace-construct 和 std::any
。但是它尝试 both 构造 std::any
参数 和 以及整个元组。
这似乎是 GCC 标准库中的一个错误。
我希望 class Config 能够在字符串键中存储任何值。为此目的,似乎 std::map 适合。不幸的是,这不是编译。
看起来 std::is_copy_constructible<std::tuple<const std::any&>>
特征失败了。我怎样才能克服它?
请在 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;
}
当我们询问 "can a std::tuple<const std::any&>
be copied" 时触发了奇怪的错误。
这最终会中断,因为它被复制最终会检查 "can std::tuple<const std::any&>
be copied" 作为中间步骤。
这是因为其中一个中间步骤涉及检查您是否可以从 std::tuple<std::any const&>
制作 std::any const&
,这反过来会询问您是否可以复制 std::tuple<std::any const&>
,这会询问如果你能从 std::tuple<std::any const&>
中得到 std::any const&
,等等
所有这些似乎都是由映射中的代码触发的,该代码将第二个参数捆绑在 std::tuple
中,然后尝试 emplace-construct 和 std::any
。但是它尝试 both 构造 std::any
参数 和 以及整个元组。
这似乎是 GCC 标准库中的一个错误。