template < typename Data >
class AbstractAlgo
{
public:
virtual void setData(Data*)=0;
AbstractAlgo();
virtual ~AbstractAlgo();
};
class Algo : public AbstractAlgo<channelData>
{
public:
virtual void setData(channelData *);
Algo();
~Algo();
};
Наследование от шаблона
Подскажите, пожалуйста, возможно ли унаследоваться от частичной или полной специализации шаблона?
То есть примерно так:
Код:
Где channelData это обычный класс.
Пока у меня попытка сборки заканчивается сообщением о невозможности найти конструктор базового класса.
Код:
template < typename Data >
class AbstractAlgo
{
public:
virtual void setData(Data*)=0;
AbstractAlgo(){};
virtual ~AbstractAlgo(){};
};
class Algo : public AbstractAlgo<int>
{
public:
virtual void setData(int *){};
Algo(){};
~Algo(){};
};
class AbstractAlgo
{
public:
virtual void setData(Data*)=0;
AbstractAlgo(){};
virtual ~AbstractAlgo(){};
};
class Algo : public AbstractAlgo<int>
{
public:
virtual void setData(int *){};
Algo(){};
~Algo(){};
};
Компилируется без проблем.
Если добавить пустые реализации конструкторов, то компилироваться перестает. Достаточно закомментировать реализацию Algo::Algo() и все снова компилируется.
И с чего вы взяли, что в данном примере наследуетесь от специализации? )
Цитата: moonug
Если добавить пустые реализации конструкторов, то компилироваться перестает. Достаточно закомментировать реализацию Algo::Algo() и все снова компилируется.
Да ладно. Полный код и версию компилятора в студию. =)
Код:
#ifndef ABSTRACTALGO_H
#define ABSTRACTALGO_H
namespace a
{
namespace algo
{
template < typename Data >
class AbstractAlgo
{
public:
virtual void setData(Data*)=0;
virtual int isAlert()=0;
AbstractAlgo();
virtual ~AbstractAlgo();
private:
};
} // end namespace algo
} // end namespace a
#endif // ABSTRACTALGO_H
#define ABSTRACTALGO_H
namespace a
{
namespace algo
{
template < typename Data >
class AbstractAlgo
{
public:
virtual void setData(Data*)=0;
virtual int isAlert()=0;
AbstractAlgo();
virtual ~AbstractAlgo();
private:
};
} // end namespace algo
} // end namespace a
#endif // ABSTRACTALGO_H
abstractalgo.cpp
Код:
#include "abstractalgo.h"
using namespace a;
using namespace algo;
template < class Data >
AbstractAlgo< Data >::AbstractAlgo()
{
}
using namespace a;
using namespace algo;
template < class Data >
AbstractAlgo< Data >::AbstractAlgo()
{
}
algo.h
Код:
#ifndef ALGO_H
#define ALGO_H
#include <abstractalgo.h>
#include <channel.h>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/circular_buffer.hpp>
namespace a {
namespace algo {
using namespace boost::accumulators;
using namespace boost;
using namespace detector;
typedef
accumulator_set<double,stats<tag::mean, tag::variance> >
accum_set;
typedef
circular_buffer< int >
circ_array;
class Algo : public AbstractAlgo<channelData>
{
public:
virtual int isAlert();
virtual void setData(channelData *);
Algo();
~Algo();
private:
accum_set _acc;
circ_array _arr;
};
} // end namespace algo
} // end namespace a
#endif // ALGO_H
#define ALGO_H
#include <abstractalgo.h>
#include <channel.h>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/math/special_functions/erf.hpp>
#include <boost/circular_buffer.hpp>
namespace a {
namespace algo {
using namespace boost::accumulators;
using namespace boost;
using namespace detector;
typedef
accumulator_set<double,stats<tag::mean, tag::variance> >
accum_set;
typedef
circular_buffer< int >
circ_array;
class Algo : public AbstractAlgo<channelData>
{
public:
virtual int isAlert();
virtual void setData(channelData *);
Algo();
~Algo();
private:
accum_set _acc;
circ_array _arr;
};
} // end namespace algo
} // end namespace a
#endif // ALGO_H
algo.cpp
Код:
#include "algo.h"
using namespace a;
using namespace algo;
Algo::Algo()
{
}
void Algo::setData(channelData * data)
{
return;
}
using namespace a;
using namespace algo;
Algo::Algo()
{
}
void Algo::setData(channelData * data)
{
return;
}
Используются внутренние спецификации.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/lto-wrapper
Целевая архитектура: x86_64-unknown-linux-gnu
Параметры конфигурации: /build/src/gcc-4.6-20110603/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --enable-multilib --disable-libstdcxx-pch --enable-checking=release
Модель многопоточности: posix
gcc версия 4.6.0 20110603 (prerelease) (GCC)
шаблоны нельзя так компилировать. необходимо перенести реализацию template <class Data> AbstractAlgo<Data>::AbstractAlgo() в .h - файл.
Цитата: Der Meister
шаблоны нельзя так компилировать. необходимо перенести реализацию template <class Data> AbstractAlgo<Data>::AbstractAlgo() в .h - файл.
А где б про это почитать?
шаблоны (за исключением полностью специализированных), наряду с макросами и встраиваемыми (inline) функциями, не попадают в объектный файл, а потому не видны компоновщику. отсюда необходимость определять их в каждой единице компиляции, в которой они используются (т. е. просто реализовывать их "на месте", в шапке модуля).
upd. пять лет назад поднималась схожая по смыслу тема - возможно, это будет вам интересно. ну и третья ссылка в списке "похожих на эту тем" (в самом низу).
Ок. Спасибо за наводку.