LINUX.ORG.RU

Шаблоная функция в качестве параметра шаблона

 , ,


0

2

Подскажите мне как можно в шаблоне от параметра типа шаблона вызвать шаблонную функцию?

struct Test
{
    int  flags;
    
    template<typename T, typename C>
    static void SetObject(T *root)
    {
        Test mdefault;
        if(mdefault.flags != flags)
        {
            root->add(new C(flags));
        }
    }
};

class BaseObject
{
public:
    template <class T >
    void *SetObject(BaseObject *root)                     
    {
         T *data = (T*)root->GetData();
         data->SetObject<BaseObject>(root);
    }
};


Последнее исправление: vvpnet (всего исправлений: 2)

1) Ты что-то делаешь сильно не так

2) Опиши человеческим языком, что должен делать код? Связный список объектов на этапе компиляции?

aido ★★
()

Хорошо бы еще и пример того, как это вызывается и что хочется получить в результате.

anonymous
()
Test mdefault;
    if(mdefault.flags != flags)

Подозреваю тут UB, mdefault.flags не инициализированы (хотя я так до конца не разобрался с default initialization, value-initialization и zero initialization, к тому же их правила меняются в каждом стандарте).

anonymous
()

У вас у Test::SetObject два шаблонных параметра. При вызове же этого метода внутри BaseObject вы указываете всего один из них. Укажите два и будет вам щасте с большой буквы Ша. Если уж нормальным языком свою задачу и проблему описать не можете.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

с каких пор отменили частичную специализацию (код в оп-посте не читал)?

anonymous
()
Ответ на: комментарий от eao197

Переписал, думаю теперь понятней будет


struct MYDATA
{
  int id;
  int pid;
  
  MYDATA():id(0),pid(0)
  {}
  
      //Шаблонная функция, которую нужно вызвать из шаблонного метода
    template<typename T, typename P> void AddObject(T *root)	//#[3]
    {
        MYDATA mdefault;
        if(mdefault.id != id)
        {
            root->add(new P(id));
        }
    }
  
}

class BaseObject
{
public:
    //Шаблонная функция, вот в ней в вызов не проходит
    template <class T > void SetObject(BaseObject *root)	//#[2]
    {
         T *data = (T*)root->GetData();
         data->AddObject<BaseObject,ParamObject>(root); //# Здесь ошибка компилер не понимает что я ему передал обычный тип объекта но с шаблонным методом
    }
};


//Как происходит сам вызов
void TestF(BaseObject *tmp)
{
  BaseObject TestBaseObject;
  TestBaseObject.SetObject<MYDATA>(tmp);			//#[1]
}

побывал по этим примерам, не помогло

vvpnet
() автор топика
Ответ на: Переписал, думаю теперь понятней будет от vvpnet

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

Далее, очень не хватает информации о том, какой у вас компилятор и какую именно ошибку он вам выдает.

Без этого приходится гадать о том, что вам нужно, с чем у вас проблемы и как эти проблемы можно устранить.

eao197 ★★★★★
()
Ответ на: Переписал, думаю теперь понятней будет от vvpnet

Если вам требовалось что-то такое:

struct A {
	template<typename T, typename P> void AddObject(T * root) {
		root->add(new P{});
	}
};

struct Params {};

class BaseObject {
public:
	template<typename T> void SetObject(BaseObject * root) {
		T * data = static_cast<T*>(root->GetRoot());
		data->template AddObject<BaseObject, Params>(root);
	}

	void add(Params * p) { delete p; }

	A * GetRoot() { return nullptr; }
};

int main() {
	BaseObject obj;
	obj.SetObject<A>(&obj);
}
то вот в таком варианте без проблем компилируется g++4.8 и g++7.2 в режиме -std=c++11.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Спасибо!

Вы меня правильно поняли! Следующий раз буду более подробно описывать вопрос! Все работает, но я не понял это (data->template AddObject<BaseObject, Params>(root)) выглядит как магия в интернете не чего не нашел внятного, я был бы признателен если дадите мне ссылку или название книги на материал по поводу (data->template), ещё раз спасибо!

vvpnet
() автор топика
Ответ на: Переписал, думаю теперь понятней будет от vvpnet

struct MYDATA

Идентификаторы написанные только большими буквами зарезервированы для макросов (негласная договоренность). Даже для enum не рекомендуется использовать имена, написанные большими буквами.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.