wykrywanie chronionych konstruktorów (ewentualnie abstrakcyjnych) klasy bazowej
Eksperymentuję z nowymi funkcjami C ++ 11. W mojej konfiguracji naprawdę chciałbym używać dziedziczenia konstruktorów, ale niestety żaden kompilator jeszcze ich nie implementuje. Dlatego próbuję symulować to samo zachowanie. Mogę napisać coś takiego:
template <class T>
class Wrapper : public T {
public:
template <typename... As>
Wrapper(As && ... as) : T { std::forward<As>(as)... } { }
// ... nice additions to T ...
};
To działa ... przez większość czasu. Czasami kod za pomocąWrapper
klasa (-y) musi użyć SFINAE, aby wykryć, w jaki sposóbWrapper<T>
może być skonstruowany. Istnieje jednak następujący problem: jeśli chodzi o rozdzielczość przeciążenia, konstruktorWrapper<T>
zaakceptuje wszelkie argumenty - ale kompilacja się nie powiedzie (a tak jestnie objęte przez SFINAE), jeśli typT
nie można ich skonstruować za pomocą tych.
Próbowałem warunkowo włączyć różne instancje szablonu konstruktora za pomocąenable_if
template <typename... As, typename std::enable_if<std::is_constructible<T, As && ...>::value, int>::type = 0>
Wrapper(As && ... as) // ...
który działa dobrze tak długo, jak:
odpowiedni konstruktorT
jestpublic
T
nie jest abstrakcyjnyMoje pytanie brzmi: jak pozbyć się powyższych dwóch ograniczeń?
Starałem się pokonać pierwsze, sprawdzając (używając SFINAE isizeof()
) czy wyrażenienew T(std::declval<As &&>()...)
jest dobrze uformowanyw ciągu Wrapper<T>
. Ale to oczywiście nie działa, ponieważ jedyny sposób, w jaki klasa pochodna może korzystać z chronionego konstruktora bazy, znajduje się na liście inicjowania elementów.
Dla drugiego nie mam pojęcia - i to jest to, czego potrzebuję więcej, ponieważ czasami jest toWrapper
który implementuje abstrakcyjne funkcjeT
, czyniąc go kompletnym typem.
Chcę rozwiązania, które:
jest poprawny zgodnie ze standardemdziała w każdym z gcc-4.6. *, gcc-4.7. * lub clang-3. *Dzięki!