Я экспериментирую с новыми функциями С++ 11. В моей настройке я бы очень хотел использовать наследующие конструкторы, но, к сожалению, компилятор пока не реализовал их. Поэтому я пытаюсь моделировать одно и то же поведение. Я могу написать что-то вроде этого:
template <class T>
class Wrapper : public T {
public:
template <typename... As>
Wrapper(As && ... as) : T { std::forward<As>(as)... } { }
// ... nice additions to T ...
};
Это работает... большую часть времени. Иногда код, использующий класс Wrapper
, должен использовать SFINAE для определения того, как можно построить такой Wrapper<T>
. Однако существует проблема: в отношении разрешения перегрузки конструктор Wrapper<T>
принимает любые аргументы, но компиляция не выполняется (и это не рассматривается SFINAE), если тип T
не может быть построен с использованием те.
Я пытался условно включить различные экземпляры шаблона конструктора, используя enable_if
template <typename... As, typename std::enable_if<std::is_constructible<T, As && ...>::value, int>::type = 0>
Wrapper(As && ... as) // ...
который отлично работает до тех пор, пока:
- соответствующий конструктор
T
равенpublic
-
T
не является абстрактным.
Мой вопрос: как избавиться от вышеуказанных двух ограничений?
Я попытался преодолеть первое, проверив (используя SFINAE и sizeof()
), правильно ли сформировано выражение new T(std::declval<As &&>()...)
внутри Wrapper<T>
. Но это, конечно, не работает, потому что единственный способ, которым производный класс может использовать свой конструктор, защищенный базой, находится в списке инициализации члена.
Для второго я понятия не имею, и это тот, который мне нужен больше, потому что иногда это Wrapper
, который реализует абстрактные функции T
, делая его полным.
Мне нужно решение, которое:
- является правильным в соответствии со стандартом
- работает в любом из gcc-4.6. *, gcc-4.7. * или clang-3. *
Спасибо!