Una plantilla no puede ser un constructor de copia. §12.8/2, nota:
Because a template constructor is never a copy constructor, the presence of such a template does not suppress the implicit declaration of a copy constructor. Template constructors participate in overload resolution with other constructors, including copy constructors, and a template constructor may be used to copy an object if it provides a better match than other constructors.
Dado que el argumento de la plantilla es const &
, su firma será exactamente la misma que la función declarada implícitamente en el caso de copia, por lo que nunca será utilizado como un constructor de copia.
Eso puede estar bien, porque en el ejemplo lo está usando como constructor de conversión. Sin embargo, los argumentos de plantilla antes de ::
son un contexto no deducido, por lo que el compilador no puede conectar A<int>::B
y resolver int
. Debido a las diversas formas de especialización de plantillas, el compilador no tiene forma de averiguar qué A
, si corresponde, califica. Podría agregar typedef A<int>::B B;
dentro de A<float>
, y luego int
y float
calificaría como U
.
Puede solucionar esto utilizando SFINAE y agregando tipos de miembro a las clases para ayudar a navegar por la jerarquía. Aquí es un demo.
#include <typeinfo>
#include <iostream>
template<typename T>
struct A
{
typedef T type;
struct B
{
B() {}
template<typename U>
B(const U& rhs, typename U::nest_A_parent * = NULL) {
std::cout << "copied from type "
<< typeid(typename U::nest_A_parent::type).name() << '\n';
}
private:
typedef A nest_A_parent;
template< typename U >
friend struct B;
};
};
int main()
{
A<int>::B x;
A<double>::B y(x);
}
Para aclarar, ¿cuál es la conversión deseada? Porque no está convirtiendo un int en un doble, sino un A :: B en un A :: B, que es una clase de otra clase. –
SSight3
@ SSight3: déjame adivinar que Robert está intentando volver a implementar punteros inteligentes con recuentos externos y asignaciones polimórficas ... – sehe
La conversión es de A :: B a A :: B para cualquier T, U. int y double son solo los ejemplos que utilicé. Y no, sehe, eso no es lo que estoy haciendo. –