1

It is one of the first times I am using boost and I am getting an error saying

BaseKey boost::bimaps::container_adaptor::detail::key_to_base_identity<BaseKey,KeyType>::operator ()(Key &) const': cannot convert argument 1 from 'const CompatibleKey' to 'Key &

and

boost::multi_index::detail::ordered_index_impl<KeyFromValue,Compare,SuperMeta,TagList,Category, AugmentPolicy>::find': no matching overloaded function found

I know most of the STL errors or at least where could they come from, but I am not experienced enough with boost to know what could be going on here. The code I have is the following, it is used to convert the values from an enum to strings and vice versa.

file.h

namespace FOO_NS::BAR_NS
{
class FooClass
{
  public:
   enum class Enum
    {
      Enum1, Enum2, Enum3, Enum4
    };

    ...
};

namespace
  {
    using results_bimap = boost::bimap<FooClass::Enum, std::string>;
    using position = results_bimap::value_type;
    const auto EnumsAsStrings = []() {
      results_bimap result;
      result.insert(position(FooClass::Enum::Enum1, "Enum1"));
      result.insert(position(FooClass::Enum::Enum2, "Enum2"));
      result.insert(position(FooClass::Enum::Enum3, "Enum3"));
      result.insert(position(FooClass::Enum::Enum4, "Enum4"));
      return result;
    };
  }  // namespace
}//namespace FOO_NS::BAR_NS

file.cpp

using namespace FOO_NS::BAR_NS;
void doSmth()
{
 ...
 std::string enumString = EnumsAsStrings().left.at(FooClass::Enum::Enum1); // Expected string "Enum1"
}

Do you see any misconception or misusage I have in this code so that this mentioned error happens?

lnlyprog
  • 23
  • 5

3 Answers3

0

You don't show enough code. Here's

All I can think of is that you might have FooClass defined in an anonymous namespace as well, and you actually have disparate declarations of the enum which are not equivalent to the compiler.

Note that if this kind of setup would be the goal, you should be able to leverage the CompatibleKey overload by using a transparent comparator instead of the default (e.g. less<void> instead of less<FooClass::enum>).

Listing

Anti-bitrot:

#include <boost/bimap.hpp>

struct FooClass{
    enum class Enum { Enum1, Enum2, Enum3, Enum4 };
};

namespace {
    using results_bimap       = boost::bimap<FooClass::Enum, std::string>;
    using position            = results_bimap::value_type;

    auto const EnumsAsStrings = []() {
        results_bimap result;
        result.insert(position(FooClass::Enum::Enum1, "Enum1"));
        result.insert(position(FooClass::Enum::Enum2, "Enum2"));
        result.insert(position(FooClass::Enum::Enum3, "Enum3"));
        result.insert(position(FooClass::Enum::Enum4, "Enum4"));
        return result;
    };
} // namespace


int main() {
    std::string enumString =
        EnumsAsStrings().left.at(FooClass::Enum::Enum1);

    assert(enumString == "Enum1");
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • 1
    Oops, we posted answers in parallel :-) – Joaquín M López Muñoz Nov 22 '22 at 14:52
  • I'm sorry I completely forgot about the namespaces. I updated the example code with the corresponding example namespaces – lnlyprog Nov 22 '22 at 15:08
  • I don't immediately see any material difference. Note that the solution with the lambda is unnecessarily inefficient. Why not simplify all the way: http://coliru.stacked-crooked.com/a/ac54ab655d915418 – sehe Nov 22 '22 at 15:14
  • The edit makes no difference: http://coliru.stacked-crooked.com/a/e2dff9a4c80dd38a – sehe Nov 22 '22 at 15:18
0

The following MCVE works, so it looks like you're not providing all the relevant information as to what your problem is:

Live Coliru Demo

#include <boost/bimap.hpp>
#include <string>

struct FooClass
{
  enum Enum{Enum1,Enum2,Enum3,Enum4};    
};

using results_bimap = boost::bimap<FooClass::Enum, std::string>;
using position = results_bimap::value_type;

const auto EnumsAsStrings = []() {
  results_bimap result;
  result.insert(position(FooClass::Enum1, "Enum1"));
  result.insert(position(FooClass::Enum2, "Enum2"));
  result.insert(position(FooClass::Enum3, "Enum3"));
  result.insert(position(FooClass::Enum4, "Enum4"));
  return result;
};

int main()
{
  std::string enumString = EnumsAsStrings().left.at(FooClass::Enum1);
}
Joaquín M López Muñoz
  • 5,243
  • 1
  • 15
  • 20
  • I updated the code with the corresponding namespaces. It compiles as well so I don't know what else could be going on in order for this code not to compile in my project – lnlyprog Nov 22 '22 at 15:12
0

Okay, so at the end it wasn't anything related to this code (directly). I was calling the lambda like this EnumsAsStrings().left.at(FooClass::Enum1) and it couldn't implicitly convert from FooClass to FooClass::Enum and that was creating the errors. Thank you to everyone who tried to answer my question!

lnlyprog
  • 23
  • 5
  • For message not related to the question itself. Need to be clearly isolated for better reading experience. – Billy Nov 24 '22 at 16:13