rttrorg / rttr

C++ Reflection Library
https://www.rttr.org
MIT License
3.17k stars 439 forks source link

Compilation error #297

Open jcxz opened 3 years ago

jcxz commented 3 years ago

The following code fails to compile:

#include <rttr/registration>
#include <rttr/type>

template <bool b>
class C1Tpl { };
using C1 = C1Tpl<false>;

struct param { };
template <typename T>
class C2Tpl { };
using C2 = C2Tpl<param>;

RTTR_REGISTRATION
{
    //rttr::registration::class_<C1>("C1");            // fails to compile
    //rttr::registration::class_<C1Tpl<false>>("C1");  // fails to compile
    rttr::registration::class_<C2>("C2");
}

int main()
{
    return 0;
}

Compilation log:

1>------ Build started: Project: RTTRbug, Configuration: Debug x64 ------
1>RTTRbug.cpp
1>D:\SourceCode\rttr\src\rttr\detail\misc\template_type_trait_impl.h(136,1): error C2672: 'rttr::type::get': no matching overloaded function found
1>D:\SourceCode\rttr\src\rttr\detail\misc\template_type_trait_impl.h(136): message : while compiling class template member function 'std::vector<rttr::type,std::allocator<rttr::type>> rttr::detail::template_type_trait<T>::get_template_arguments(void)'
1>        with
1>        [
1>            T=non_ref_type
1>        ]
1>D:\SourceCode\rttr\src\rttr\detail\type\type_data.h(300): message : see reference to function template instantiation 'std::vector<rttr::type,std::allocator<rttr::type>> rttr::detail::template_type_trait<T>::get_template_arguments(void)' being compiled
1>        with
1>        [
1>            T=non_ref_type
1>        ]
1>D:\SourceCode\rttr\src\rttr\detail\type\type_data.h(330): message : see reference to class template instantiation 'rttr::detail::template_type_trait<T>' being compiled
1>        with
1>        [
1>            T=non_ref_type
1>        ]
1>D:\SourceCode\rttr\src\rttr\detail\type\type_impl.h(304): message : see reference to function template instantiation 'std::unique_ptr<rttr::detail::type_data,std::default_delete<rttr::detail::type_data>> rttr::detail::make_type_data<T>(void)' being compiled
1>        with
1>        [
1>            T=non_ref_type
1>        ]
1>D:\SourceCode\rttr\src\rttr\detail\type\type_impl.h(371): message : see reference to function template instantiation 'rttr::type rttr::detail::create_or_get_type<non_ref_type>(void) noexcept' being compiled
1>D:\SourceCode\rttr\src\rttr\detail\registration\registration_impl.h(99): message : see reference to function template instantiation 'rttr::type rttr::type::get<Class_Type>(void) noexcept' being compiled
1>        with
1>        [
1>            Class_Type=C1Tpl<false>
1>        ]
1>D:\SourceCode\rttr\src\rttr\detail\registration\registration_impl.h(98): message : while compiling class template member function 'rttr::registration::class_<C1Tpl<false>,rttr::type_list<>>::class_(rttr::string_view)'
1>D:\SourceCode\VisualStudio\RTTRbug\RTTRbug\RTTRbug.cpp(22): message : see reference to function template instantiation 'rttr::registration::class_<C1Tpl<false>,rttr::type_list<>>::class_(rttr::string_view)' being compiled
1>D:\SourceCode\VisualStudio\RTTRbug\RTTRbug\RTTRbug.cpp(22): message : see reference to class template instantiation 'rttr::registration::class_<C1Tpl<false>,rttr::type_list<>>' being compiled
1>D:\SourceCode\rttr\src\rttr\detail\misc\template_type_trait_impl.h(136,1): error C2974: 'rttr::type::get': invalid template argument for 'T', type expected
1>D:\SourceCode\rttr\src\rttr\type.h(323): message : see declaration of 'rttr::type::get'
1>Done building project "RTTRbug.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

It looks like RTTR wrongly handles non-template arguments (false). It tries to call rttr::type::get<false>().

Illation commented 3 years ago

I had a similar issue, which looks a bit like this:

template<int i>
class Foo{};

// [...]

rttr::type const foo0Type = rttr::type::get<Foo<0>>(); // same compiler error as OP here
sbond75 commented 1 year ago

I am also having this issue. Are there any workarounds or fixes for it?

sbond75 commented 1 year ago

Found a workaround by using a wrapper that hides the original template class:

#include <rttr/registration>
#include <rttr/type>

template <bool b>
class C1Tpl { };
using C1 = C1Tpl<false>;

struct param { };
template <typename T>
class C2Tpl { };
using C2 = C2Tpl<param>;

struct Wrapper { C1 c1; };

RTTR_REGISTRATION
{
    //rttr::registration::class_<C1>("C1");            // fails to compile
    //rttr::registration::class_<C1Tpl<false>>("C1");  // fails to compile
    rttr::registration::class_<C2>("C2");
    // workaround:
    rttr::registration::class_<Wrapper>("C1");
}

int main()
{
    return 0;
}