Estoy experimentando con las nuevas características de C++ 11. En mi configuración, me encantaría usar constructores heredadores, pero desafortunadamente ningún compilador los implementa aún. Por lo tanto, estoy tratando de simular el mismo comportamiento. Puedo escribir algo como esto:detección de constructores protegidos de la clase base (posiblemente abstracta)
template <class T>
class Wrapper : public T {
public:
template <typename... As>
Wrapper(As && ... as) : T { std::forward<As>(as)... } { }
// ... nice additions to T ...
};
Esto funciona ... la mayor parte del tiempo. A veces, el código que usa la (s) clase (s) Wrapper
debe usar SFINAE para detectar cómo se puede construir un Wrapper<T>
. Sin embargo, existe la siguiente cuestión: en cuanto a la resolución de sobrecarga, el constructor de Wrapper<T>
aceptará cualquier argumento, pero la compilación falla (y esto es no cubierto por SFINAE) si el tipo T
no se puede construir utilizando esos.
yo estaba tratando de permitir condicionalmente las diferentes instancias de la plantilla constructor usando enable_if
template <typename... As, typename std::enable_if<std::is_constructible<T, As && ...>::value, int>::type = 0>
Wrapper(As && ... as) // ...
que funciona bien siempre y cuando:
- el constructor adecuado de
T
espublic
T
no es abstracto
Mi pregunta es: ¿cómo deshacerse de las dos limitaciones anteriores?
I tratado de superar la primera mediante la comprobación (usando SFINAE y sizeof()
) si la expresión new T(std::declval<As &&>()...)
está bien formado dentro deWrapper<T>
. Pero esto, por supuesto, no funciona, porque la única forma en que una clase derivada puede usar el constructor protegido de su base se encuentra en la lista de inicialización de miembros.
Para la segunda, no tengo ni idea, y es la que necesito más, porque a veces es la Wrapper
la que implementa las funciones abstractas de T
, lo que la hace un tipo completo.
Quiero una solución que:...
- es correcto según el estándar
- obras en cualquiera de gcc-4.6 *, gcc-4.7 * o sonido metálico-3 *
Gracias!
Tengo prisa, pero tal vez http://stackoverflow.com/questions/8984013/can-sfinae-detect-private-access-violations puede ayudar aquí, no contaría con gcc 4.6 hacerlo bien aunque – PlasmaHH
El control de acceso es un poco complicado aquí: si usas 'sizeof()', el compilador verificará toda la expresión, acceso incluido, pero luego se verifica el acceso ** desde el contexto de la expresión **, que falla en el caso de constructores protegidos; todo lo que no sea 'sizeof' funciona solo al nivel de resolución de sobrecarga e inferencia de tipo, por lo que las violaciones de acceso no activarán SFINAE, pero entonces, no veo la manera de hacer algo con un constructor, ya que no se puede pasar como un argumento de plantilla . En cuanto al soporte del compilador, me complacerá si ** cualquier ** de los anteriores acepta el código. –