-1

I'd like to have class Config able to store literally any value within a string key. For that purpose it seems that std::map fits. Unfortunately this isn't compiling.

That looks like that std::is_copy_constructible<std::tuple<const std::any&>> trait fails. How can I overcome that? Please find source at https://github.com/marchevskys/VisualEngine.

The code idea the same as follows,

#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;
}

That compiled on MS Visual Studio, and with older than 9.1.0 g++, but won't compile on g++ 9.1.0.

You can get the same error with:

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

int main()
{
  bool b = std::is_copy_constructible< std::tuple<const std::any&> >::value );
  (void)b;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • try to compile with `-stdlib=libc++` flag – Ahmed Kamal Jun 23 '19 at 17:42
  • 2
    You need to show your compilation command and your compilation errors. – n. m. could be an AI Jun 23 '19 at 18:06
  • Thank you for your answers, I changed a code so not using std::any but std::variant. – Alexander Pushkar Jun 23 '19 at 18:12
  • 1
    Your problem could be anything, up to and including you forgot to include a header file. [MCVE] is needed to solve your problem. – Yakk - Adam Nevraumont Jun 23 '19 at 19:03
  • 2
    The code compiled for me with gcc 9.1.0 (after a few additions since the code in the question is incomplete). So we would definitely need 1) enough code to compile on its own; 2) the command line used to compile; and 3) the exact error message (with or without your interpretation of the error message). – JaMiT Jun 23 '19 at 21:08
  • @JaMiT I've added code snippet able to build. For build I'm using CMake where C++ language standard set to C++17. – Alexander Pushkar Jun 24 '19 at 10:08
  • The build output is too long for put here, [ 26%] Building CXX object CMakeFiles/VisualEngine.dir/src/Config.cpp.o onfig.cpp:2: /usr/include/c++/9.1.0/type_traits: In instantiation of 'struct std::__and_ >, std::is_constructible, const std::tuple&> >': /usr/include/c++/9.1.0/any:181:58: required by substitution of 'template, std::is_constructible<_Tp, _ValueType&&> >:: – Alexander Pushkar Jun 24 '19 at 18:48
  • @AhmedM.Kamal I've tried that without success. – Alexander Pushkar Jun 24 '19 at 18:53
  • @Yakk-AdamNevraumont I've added a minimal example demonstrated the issue. – Alexander Pushkar Jun 24 '19 at 19:14
  • @AlexanderPushkar Please don't try to bypass the limitations of the site. One reason comments are limited in length is to discourage people from dumping data into the comments when they should add the data to the question itself. – JaMiT Jun 25 '19 at 14:20

1 Answers1

1

The strange error is triggered when we ask "can a std::tuple<const std::any&> be copied".

This ends up breaking, because it being copied ends up checking "can std::tuple<const std::any&> be copied" as an intermediate step.

This is because one of the intermediate steps involves checking if you can make a std::any const& from a std::tuple<std::any const&>, which in turn asks if you can copy a std::tuple<std::any const&>, which asks if you can make a std::any const& from a std::tuple<std::any const&>, etc.

All of this seems to be triggered by code in the map that bundles the 2nd argument up in a std::tuple, then tries to emplace-construct the std::any with it. But it tries both constructing the std::any with the arguments and with the tuple as a whole.

This seems to be a mistake in the GCC standard library.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524