billyquith / ponder

C++ reflection library with Lua binding, and JSON and XML serialisation.
http://billyquith.github.io/ponder/
Other
640 stars 93 forks source link

Compile error for ValueVisitor example #62

Open Weeena opened 7 years ago

Weeena commented 7 years ago

It seems that (at least in my environment = VS2015) your ValueVisitor example leads to a compile error. I had problems with my own ValueVisitor, so I tried to reproduce your ValueVisitor example to see if the behaviour is the same. It looks as if that would be the case.

When I compile your ValueVisitor example (which can be found here: ValueVisitor example) I get the following compiler error:

\detail\variant.hpp(316): error C3066: there are multiple ways that an object of this type can be called with these arguments
\test.cpp(3933): note: could be 'PropertyEditor *EditorFactory::operator ()(bool)'
\test.cpp(3938): note: or       'PropertyEditor *EditorFactory::operator ()(long)'
\test.cpp(3943): note: or       'PropertyEditor *EditorFactory::operator ()(double)'
\test.cpp(3948): note: or       'PropertyEditor *EditorFactory::operator ()(ponder::IdRef)'
\test.cpp(3953): note: or       'PropertyEditor *EditorFactory::operator ()(const ponder::EnumObject &)'
\test.cpp(3958): note: or       'PropertyEditor *EditorFactory::operator ()(const ponder::UserObject &)'
\detail\variant.hpp(316): note: while trying to match the argument list '(const ponder::String)'
\detail\variant.hpp(313): note: while compiling class template member function 'PropertyEditor mapbox::util::detail::dispatcher<F,V,R,ponder::String,ponder::EnumObject,ponder::UserObject>::apply_const(const V &,F)'
    with
    [
        F=EditorFactory &,
        V=const ponder::Value::Variant,
        R=PropertyEditor *
    ]

It seems that the compiler does not know which of the operators to call if the Value is a string.

Am I doing something wrong?

billyquith commented 7 years ago

The example is from the CAMP code. I haven't used/tested it. I've created an "example inserter" for the docs, so that the examples get compiled to check they work, but clearly I haven't moved this one.

CAMP used std::string for everything. I changed this to Id and IdRef for more efficient passing of string references. I did search and replace for const std::string&, but in some places we want to reference the value type not the reference type (e.g. when returning names).

If you change ponder::IdRef to const std::string& I think it should work.

Weeena commented 7 years ago

Unfortunately, then I get a PONDER_TYPE_NOT_REGISTERED error:

detail\typeid.hpp(52): error C2039: 'PONDER_TYPE_NOT_REGISTERED': is not a member of 'ponder::NoType'

But maybe that's a different story?

billyquith commented 7 years ago

Well it's looking for '(const ponder::String)' so maybe try that. (I haven't used this feature)

Weeena commented 7 years ago

Unfortunately, it makes no difference. As usual with templates, the comile error is rather lengthy, the topmost part is:

\detail\typeid.hpp(52): error C2039: 'PONDER_TYPE_NOT_REGISTERED': is not a member of 'ponder::NoType'
  \ponder\type.hpp(43): note: see declaration of 'ponder::NoType'
  \ponder\detail\typeid.hpp(49): note: while compiling class template member function 'const char *ponder::detail::StaticTypeId<ponder::NoType>::get(bool)'
  \ponder\detail\typeid.hpp(78): note: see reference to function template instantiation 'const char *ponder::detail::StaticTypeId<ponder::NoType>::get(bool)' being compiled
  \ponder\detail\typeid.hpp(78): note: see reference to class template instantiation 'ponder::detail::StaticTypeId<ponder::NoType>' being compiled
  \ponder\detail\typeid.hpp(125): note: see reference to function template instantiation 'const char *ponder::detail::staticTypeId<T>(void)' being compiled
      with
      [
          T=ponder::NoType
      ]

Again, could that be a different story that does not anymore has to do with string?

BTW, I thought I try something out with a ValueVisitor. Since a fix seems not so clear, I am currently reworking my code to use an old-fashioned switch statement.

billyquith commented 7 years ago

Well it looks like an uninitialised Value may have been passed to the visitor.

Weeena commented 7 years ago

I tried to iterate over the properties of a UserObject in the following way:

    const ponder::Class& metaClass = obj.getClass();
    for (auto&& iter : metaClass.propertyIterator())
    {
        const ponder::Property& property = *iter.value().get();
        ponder::Value val = property.get(obj);
        val.visit(visitor);
    }