#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);
}
Этот код определяет константный и неконстантный тип представления, как псевдонимы шаблона view_tpl<Const>
. Должно быть так, что view
неявно конвертируется в const_view
, но не наоборот.
Это Const
равно true
, определенный конструктор копирования это разрешает, и компилятор генерирует дополнительный конструктор копирования по умолчанию. Если Const
равно false
, то определенный конструктор копирования заменяет конструктор копирования по умолчанию.
Это неявное преобразование должно происходить при вызове f(vw)
.
В приведенном выше примере он работает правильно code.
Но если я добавлю аргумент в шаблоны (int N
) и включу f
и псевдонимы двух типов в шаблоны, он больше не будет работать:
#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);
}
Вместо преобразования view_tpl<0, true>
в view_tpl<0, false>
компилятор пытается выполнить только прямую подстановку шаблона и завершается неудачно:
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);
| ^
Есть ли способ заставить эту работу не менять слишком много код? (Реальный код более сложный, чем этот пример)