2014-11-20 1 views
0

Я хочу написать вспомогательную структуру, проверяющую статическое условие на классы. Если условие истинно, объект должен быть выделен в куче, а указатель на объект должен быть возвращен обратно в std :: vector.Ошибка цикла делегирования шаблона C++

Эти объекты выглядят как:

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(); 
} 

В теории конструктор в структуре конд должен вызовите конструктор его родителя, но C++ 11 также ввел функцию вызова конструкторов в constru (делегация). Таким образом, швы компилятора думать, что я хочу, чтобы вызвать конструктор в том же классе, что приводит к ошибке:

./main.cpp:83:34: error: constructor for 'cond' creates a delegation cycle [-Wdelegating-ctor-cycles] 

Просто перемещение вектора в глобальную области видимости и удаление аргументов конструктора работает, но я бы предпочитаю Иной решение.

Можно ли сказать компилятору как-то интерпретировать cond (_b) правильно?

ответ

0

Просто сделайте это явно какая часть класса вы используете, давая полный типа:

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...>

EDIT: Что касается ошибки, то никакой конструктор не найден, обратите внимание, что это правда. Этот класс:

template<class... R> 
struct cond {}; 

Не один, так что вы должны добавить что-то вроде этого, и он должен работать:

template<class... R> 
struct cond 
{ 
    template<typename...T> 
    cond(T...) 
    { 

    } 
}; 
+0

Это приводит к ошибке: './main.cpp:83:34 : error: нет соответствующего конструктора для инициализации 'cond <>' '(Используется Clang, но не работает с GCC) – Mense

+0

@Mense - это правильно, так как в классе« хвост »нет конструктора. Вам нужно добавить его. Я отредактировал ответ с этой информацией. –

+0

Спасибо; работает сейчас. – Mense