Tomasu / LuaGlue

C++11 Lua 5.2 Binding Library
zlib License
79 stars 22 forks source link

const LuaGlueClass::method does not compile #13

Closed JMLX42 closed 10 years ago

JMLX42 commented 10 years ago

Commit a31268d4cb8324ceb28e83c74e508f901361ce51 does not compile with GCC 4.8.1:

template
LuaGlueClass<_Class> &method(const std::string &name, void (_Class::*fn)(_Args...))
{
// ...
}

template
LuaGlueClass<_Class> &method(const std::string &name, void (_Class::*fn)(_Args...) const)
{
// ...
}
lib/LuaGlue/include/LuaGlue/LuaGlueClass.h:251:25: error: ‘template LuaGlueClass<_Class>& LuaGlueClass<_Class>::method(const string&, _Ret (_Class::*)(_Args ...)const) [with _Ret = _Ret; _Args = {_Args ...}; _Class = const std::basic_string]’ cannot be overloaded
   LuaGlueClass<_Class> &method(const std::string &name, _Ret (_Class::*fn)(_Args...) const)
                         ^
lib/LuaGlue/include/LuaGlue/LuaGlueClass.h:241:25: error: with ‘template LuaGlueClass<_Class>& LuaGlueClass<_Class>::method(const string&, _Ret (_Class::*)(_Args ...)) [with _Ret = _Ret; _Args = {_Args ...}; _Class = const std::basic_string]’
   LuaGlueClass<_Class> &method(const std::string &name, _Ret (_Class::*fn)(_Args...))

The problem is in the fact that the constness of the function pointer is not enough to allow the overload. According to §13.1 of the standard:

Parameter declarations that differ only in the presence or absence of const and/or volatile are equivalent. That is, the const and volatile type-specifiers for each parameter type are ignored [...]

Did you really manage to compile this part? One of the fixes would be to separate method() and constMethod() methods. What do you think?

Tomasu commented 10 years ago

It compiles fine in 4.8.2. Interesting. Check out foo.cpp. Yeah, if according to the standard, the const method() should be renamed to constMethod().

JMLX42 commented 10 years ago

Wow that's strange indeed...

JMLX42 commented 10 years ago

Also LuaGlueObject.h does not "compile" because of LuaGlueObjectImpl::vget() returns a void * when it is expected to return a const void* when _Class is a const "something".

Tomasu commented 10 years ago

Hm, yeah, that makes sense. have to cast that or something.

JMLX42 commented 10 years ago

const_cast won't work at 100% because some times are not usable with const_cast. I tried to have different overload of vget() using std::enable_if and std::is_const but it doesn't work.

Simply changing

typedef _Class Type;

into:

typedef std::remove_const<_Class> Type;

everywhere in LuaGlueObject.h won't work either.

I think that in general you should use std::remove_const on all your templates: it's ok for objects to get const values when the template is the corresponding non-const type. It doesn't work the other way around, which is why we have so much trouble...

Tomasu commented 10 years ago

Are you doing anything special to compile it? Adding any extra flags?

JMLX42 commented 10 years ago

Nope... doesn't compile... I changed LuaGlueClass.method into LuaGlueClass.constMethod when relevant. But then I got that LuaGlueObject problem. On Dec 2, 2013 8:13 PM, "Thomas Fjellstrom" notifications@github.com wrote:

Are you doing anything special to compile it? Adding any extra flags?

— Reply to this email directly or view it on GitHubhttps://github.com/Tomasu/LuaGlue/issues/13#issuecomment-29647724 .

JMLX42 commented 10 years ago

I think I'll add a constness example you can build/test against. How does that sound?

Tomasu commented 10 years ago

Yeah, I think that'd be useful.

Tomasu commented 10 years ago

Also, have you updated your remaining pull requests?

JMLX42 commented 10 years ago

For some reasons your examples compile fine... but my code does not. I'm still investigating.

Tomasu commented 10 years ago

I'm going to assume this has been solved. Please re open if not.