#include <type_traits>
template<bool Const>
struct view_tpl {
using value_type = std::conditional_t<Const, const int, int>;
value_type* ptr;
view_tpl() = default;
view_tpl(const view_tpl<false>& other) : ptr(other.ptr) { }
};
using view = view_tpl<false>;
using const_view = view_tpl<true>;
void read(const const_view& vw) { }
int main() {
view vw;
read(vw);
}
This code defines a const and a non-const view type, both as aliases to a view_tpl<Const>
template. It should be such that view
is implicitly convertible to const_view
, but not the other way around.
It Const
is true
, the defined copy-constructor enables this, and the compiler generates an additional default copy-constructor. If Const
is false
the defined copy-constructor replaces the default copy-constructor.
This implicit conversion should happen when f(vw)
is called.
It works correctly in the above code.
But if I add an argument to the templates (int N
), and turn f
and the two type aliasses into templates, it no longer works:
#include <type_traits>
template<int N, bool Const>
struct view_tpl {
using value_type = std::conditional_t<Const, const int, int>;
value_type* ptr;
view_tpl() = default;
view_tpl(const view_tpl<N, false>& other) : ptr(other.ptr) { }
};
template<int N> using view = view_tpl<N, false>;
template<int N> using const_view = view_tpl<N, true>;
template<int N>
void read(const const_view<N>& vw) { }
int main() {
view<0> vw;
read(vw);
}
Instead of doing the conversion of view_tpl<0, true>
to view_tpl<0, false>
, the compiler only tries a direct template substitution and fails:
main.cpp: In function 'int main()':
main.cpp:20:12: error: no matching function for call to 'read(view<0>&)'
20 | read(vw);
| ^
main.cpp:16:6: note: candidate: 'template<int N> void read(const_view<N>&)'
16 | void read(const const_view<N>& vw) { }
| ^~~~
main.cpp:16:6: note: template argument deduction/substitution failed:
main.cpp:20:12: note: template argument 'false' does not match 'true'
20 | read(vw);
| ^
Is there a way to make this work without changing too much of the code? (The real code is more complex than this example)
Aucun commentaire:
Enregistrer un commentaire