Используйте std :: map с std :: any в качестве типа значения - PullRequest
0 голосов
/ 23 июня 2019

Я бы хотел, чтобы класс 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;
}

1 Ответ

1 голос
/ 24 июня 2019

Странная ошибка возникает, когда мы спрашиваем "можно ли скопировать std::tuple<const std::any&>".

Это заканчивается разрывом, потому что копирование завершается проверкой "можно std::tuple<const std::any&> быть скопировано" в качестве промежуточного шага.

Это потому, что один из промежуточных шагов включает проверку, можно ли сделать std::any const& из std::tuple<std::any const&>, который, в свою очередь, спрашивает, можете ли вы скопировать std::tuple<std::any const&>, который спрашивает, можете ли вы сделать std::any const& от std::tuple<std::any const&> и т. д.

Все это, кажется, запускается кодом на карте, который связывает 2-й аргумент в std::tuple, а затем пытается скомпоновать-1015 * с ним. Но он пытается и построить std::any с аргументами и с кортежем в целом.

Это кажется ошибкой в ​​стандартной библиотеке GCC.

...