Я хочу написать вспомогательную структуру, проверяющую статические условия на классах. Если условие истинно, объект должен быть размещен в куче, а указатель на объект должен быть возвращен обратно в std :: vector.
Эти объекты выглядят так:
class BASE {
public:
virtual void func() = 0;
};
class A : public BASE {
public:
const static int I = 0;
void func() {
std::cout << "CLASS A" << endl;
}
};
class B : public BASE {
public:
const static int I = 1;
void func() {
std::cout << "CLASS B" << endl;
}
};
Структура чека:
template<class... R>
struct cond {};
template<class T, class... R>
struct cond<T, R...> : cond<R...> {
cond( vector<BASE *> &_b ) : cond( _b ) {
if( T::I == 1 )
_b.emplace_back( new T() );
}
};
И где-то в основной функции:
std::vector<BASE *> b;
cond<A, B> t(b);
for( auto *x : b ) {
x->func();
}
Теоретически конструктор в структуре cond должен вызывать конструктор своего родителя, но в C ++ 11 также появилась возможность вызывать конструкторы в конструкторах (делегирование). Таким образом, компилятор кажется, что я хочу вызвать конструктор из того же класса, что приводит к этой ошибке:
./main.cpp:83:34: error: constructor for 'cond' creates a delegation cycle [-Wdelegating-ctor-cycles]
Простое перемещение вектора в глобальную область и удаление аргументов конструктора работает, но я бы предпочел другое решение.
Можно ли сказать компилятору как-то интерпретировать cond (_b), верно?
Просто укажите, какую часть класса вы используете, дав полный тип:
template<class... R>
struct cond {};
template<class T, class... R>
struct cond<T, R...> : cond<R...> {
cond( vector<BASE *> &_b ) : cond<R...>( _b ) {
if( T::I == 1 )
_b.emplace_back( new T() );
}
};
После :
в конструкторе укажите полный тип, в точности так, как он указан в списке наследования класса — cond<R...>
РЕДАКТИРОВАТЬ:
Что касается ошибки, что конструктор не найден, обратите внимание, что это правда. Этот класс:
template<class... R>
struct cond {};
Не имеет, так что вы должны добавить что-то вроде этого, и это должно работать:
template<class... R>
struct cond
{
template<typename...T>
cond(T...)
{
}
};