我有这两节课:
template <typename GeomType>
class InputCSV
{
public:
InputCSV(DataSet<GeomType> * ds) : ds(ds) {}
virtual ~InputLoaderCSV() = default;
DataSet<GeomType> * ds;
};
和
template <typename GeomType>
struct DataSet
{
template <typename LoaderType>
static DataSet<GeomType> Create()
{
DataSet<GeomType> ds;
ds.fileName = "something";
ds.input = std::make_shared<LoaderType<GeomType>>(&ds);
return std::move(ds);
};
DataSet(const DataSet & ds) = delete;
DataSet(DataSet && ds)
{
this->fileName = std::move(ds.fileName);
this->input = std::move(ds.input);
this->input->ds = this;
ds.input = nullptr;
}
std::string fileName;
std::shared_ptr<InputLoader<GeomType>> input;
protected:
DataSet() : input(nullptr) {}
}
现在在代码中的某个地方,我想做
auto ds = DataSet<Line>::Create<InputCSV>();
其中Line是我拥有的一些结构。但是,这不起作用,并且出现此错误:
error C2672: 'DataSet<Line>::Create': no matching overloaded function found
error C3206: 'DataSet<Line>::Create': invalid template argument for 'LoaderType', missing template argument list on class template 'InputLoaderCSV'
note: see declaration of 'DataSet<Line>::Create'
error cannot access protected member declared in class 'DataSet<Line>'
note: see declaration of 'DataSet<Line>::DataSet' note: see declaration of 'DataSet<Line>'
是否有解决方案来拥有这种“语法”,或者我必须写
auto ds = DataSet<Line>::Create<InputCSV<Line>>();
并更改
ds.input = std::make_shared<LoaderType<GeomType>>(&ds);
到
ds.input = std::make_shared<LoaderType>(&ds);
在此示例中,我不喜欢InputCSV中的“重复项”,因为没有其他内容了。
答案 0 :(得分:3)
您要寻找的是template template parameter。由于InputCSV
是模板类型,因此必须指定其模板参数。如果将Create
更改为使用模板模板参数,则可以将模板传递给Create
并像使用其他模板一样使用它。为此,您需要使用
template <template<typename> typename LoaderType>
// pre C++17 you have to use template <template<class> class LoaderType> instead
static DataSet<GeomType> Create()
{
DataSet<GeomType> ds;
ds.fileName = "something";
ds.input = std::make_shared<LoaderType<GeomType>>(&ds);
return std::move(ds);
}
然后将其保留为
auto ds = DataSet<Line>::Create<InputCSV>();
现在LoaderType
是一种模板类型,它采用可以在函数内部指定的单个模板参数。