Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding a member function that returns a std::map does not compile, while returning a std::vector does #1515

Open
OndrejPopp opened this issue Jul 23, 2023 · 6 comments

Comments

@OndrejPopp
Copy link

OndrejPopp commented Jul 23, 2023

Hello, here I am again!
And this time with a Phd test case,
ThePhd.h.txt

/*
    SPDX-FileCopyrightText: 2023 Ondrej Popp
    SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/

#pragma once

#include <lua.hpp>

#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include <string>
#include <vector>
#include <map>

class ThePhd
{
 public:
    ThePhd() = default;

    const std::vector<std::string>& thePhdVector() const
    {
        return m_thePhdVector;
    } 

    const std::map<std::string, std::string>& thePhdMap() const
    {
        return m_thePhdMap;
    }

 private:
    std::vector<std::string> m_thePhdVector;

    std::map<std::string, std::string> m_thePhdMap;
};

void bindThePhd(sol::table& t)
{
    t.new_usertype<ThePhd>("ThePhd",
     sol::constructors<ThePhd()>(),
    
    // this one does compile,
    "thePhdVector", &ThePhd::thePhdVector,
    
    // while this one does not,
    "thePhdMap", &ThePhd::thePhdMap,

    // but this one does
    "wrapThePhdMap", [](const ThePhd& self)
      {return sol::as_table_t<std::map<std::string, std::string>>(self.thePhdMap());}
   ); 
}

As commented here above, while trying to bind the Phd, binding thePhdVector does compile, while binding thePhdMap does not. However, when you wrap that inside a sol::as_table_t it does compile, which is a good workaround, but I think the standard binding should work as well for the Phd?

And here is the compiler trace,
thePhdTrace.txt

It appears to be failing around here,

/src/Multimedia/VideoEditors/OpenIO/OpenIo/Cxx/Bridges/Lua/Sol/OpenIo/Tree/ThePhd.h:40:27:   required from here
/usr/local/include/sol/usertype_container.hpp:1191:46: error: unable to deduce ‘auto&’ from ‘i.sol::container_detail::usertype_container_default<std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, void>::iter::it’
 1191 |                                 auto& it = i.it;
      |                                            ~~^~
/usr/local/include/sol/usertype_container.hpp:1191:39: note:   couldn’t deduce template parameter ‘auto’
 1191 |                                 auto& it = i.it;
      |                                       ^~
/usr/local/include/sol/usertype_container.hpp:1192:47: error: ‘struct sol::container_detail::usertype_container_default<std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >, void>::iter’ has no member named ‘end’
 1192 |                                 auto& end = i.end;
      |                                             ~~^~~

Ok, that was my Phd test case :)
Tx, and have a nice day,
Ondrej

@midwitdev
Copy link

Hello, I have the same problem. Very frustrating

@OndrejPopp
Copy link
Author

Good morning! Well it's not that bad... You need to write these bindings anyway so it's not too much effort to wrap the map. In addition I have found that std::optional doesn't work either, so you need to return it from the lambda as well, but without wrapping it inside sol::as_table_t because that does not make sense for a std::optional. There could be more, but I don't remember that right now, I didn't feel like commenting on it all, so I would have to look at the code. In any case, I was able to fix everything that didn't work, generally by returning it from a lambda. So that's not all that bad...

Oh yeah, there is an other thing, from the top of my head, if I remember correctly, optional parameters in a constructor do not work either so you need to expand those. For example, if you have T::T(t1 a, t2 b, t3 c = d) you need to expand that into,
sol::constructors<T(t1 a, t2 b),T(t1 a, t2 b, t3 c)>() and so on if you have more optional parameters in your constructor.

For the rest, it works like a charm, tx PhD!
image

@roman-orekhov
Copy link

@OndrejPopp
you can fix the offending lines like this

				auto& it = i.it();
				auto& end = i.sen();

it should compile. But in my case using pairs doesn't actually run through the std::map anyway.

@OndrejPopp
Copy link
Author

OndrejPopp commented May 9, 2024

@roman-orekhov Ok, tx! But yes, std::map uses pairs so if that doesn't work then you still need to wrap it...

btw,
it.sen() should be it.end() ?

@roman-orekhov
Copy link

No, with it.end() it won't compile. sen in from sentinel

@OndrejPopp
Copy link
Author

Ok. Tx.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants