i'm trying compile example, variadic class template inherits variadic amount of bases, each of implements different operator[]:
#include <iostream> template <typename t> struct field { typename t::value_type storage; typename t::value_type &operator[](const t &c) { return storage; } }; template<typename... fields> struct ctmap : public field<fields>... { }; int main() { struct age { typedef int value_type; }; struct last_name { typedef std::string value_type; }; ctmap<last_name, age> person; person[last_name()] = "smith"; person[age()] = 104; std::cout << "hello world!" << std::endl; return 0; } when compile gcc (debian 4.9.2-10), following error
main.cpp: in function ‘int main()’: main.cpp:22:23: error: request member ‘operator[]’ ambiguous person[last_name()] = "smith"; ^ main.cpp:7:27: note: candidates are: typename t::value_type& field<t>::operator[](const t&) [with t = main()::age; typename t::value_type = int] typename t::value_type &operator[](const t &c) { ^ main.cpp:7:27: note: typename t::value_type& field<t>::operator[](const t&) [with t = main()::last_name; typename t::value_type = std::basic_string<char>] main.cpp:23:17: error: request member ‘operator[]’ ambiguous person[age()] = 104; ^ main.cpp:7:27: note: candidates are: typename t::value_type& field<t>::operator[](const t&) [with t = main()::age; typename t::value_type = int] typename t::value_type &operator[](const t &c) { ^ main.cpp:7:27: note: typename t::value_type& field<t>::operator[](const t&) [with t = main()::last_name; typename t::value_type = std::basic_string<char>] why ambiguous?
a portable way do want roughly:
template<class...ts> struct operator_index_inherit {}; template<class t0, class t1, class...ts> struct operator_index_inherit<t0, t1, ts...>: t0, operator_index_inherit<t1, ts...> { using t0::operator[]; using operator_index_inherit<t1, ts...>::operator[]; }; template<class t0> struct operator_index_inherit<t0>: t0 { using t0::operator[]; }; then:
template<class... fields> struct ctmap : operator_index_inherit<field<fields>...> { using base = operator_index_inherit<field<fields>...>; using base::operator[]; }; here linearly inherit each of types, , using operator[] on our parents.
if using field<fields>::operator[]...; not have this.
some care has taken constructors (which did not take), might not need this.
what going wrong depends on details of standard less of. basically, mixing operators , inheritance , overloading in complex way. if code standard compliant (which may or may not be), compliant in way compilers die on.
Comments
Post a Comment