Thanks to @Jarod42 @LouisGo and @Oersted, I understood that the concept solution would be the best. My solution is
#include <vector>
template <typename T>
concept Container = requires(T t) {
std::begin(t);
std::end(t);
};
template <typename A, typename B>
B convert(A a)
{
return B{a};
}
template <Container A, typename B>
B convert(A a)
{
return B{a.front()};
}
template <typename A, Container B>
B convert(A a)
{
return B{};
}
template <Container A, Container B>
B convert(A a)
{
return B{};
}
template <typename T>
struct A
{
T v_{};
template <typename U>
void assign(const A<U>& value)
{
v_ = convert<U, T>(value.v_);
}
};
int main(int argc, const char *argv[])
{
A<int> i;
A<std::vector<int> > vi;
vi.assign(i);
return 0;
}